This adds the new constructor required by the resolution of LWG 2583.
The new symbols matched the greedy patterns for strings in old symbol
versions, so I made them much more precise. It's possible some symbols
that are supposed to be exported will now not match, but I checked
that all symbols in all our baselines_symbols.txt files still match
(using the attached python tool, symverck.py).

        * config/abi/pre/gnu.ver (GLIBCXX_3.4, GLIBCXX_3.4.21): Use more
        precise patterns for basic_string constructors.
        (GLIBCXX_3.4.23): Export new constructors.
        * doc/xml/manual/intro.xml: Document LWG 2583 status.
        * doc/html/*: Regenerate.
        * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
        (basic_string(const basic_string&, size_type, const Alloc&)): Add
        new constructor for LWG 2583.
        (basic_string(const basic_string&, size_type, size_type)): Remove
        default argument.
        [!_GLIBCXX_USE_CXX11_ABI]: Likewise.
        * include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]: Define it.
        * testsuite/21_strings/basic_string/cons/char/8.cc: New test.
        * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: New test.

Tested x86_64-linux and powerpc64-linux, with old and new string ABIs.

Committed to trunk.

commit 1ce0e122a203addfa3930f3cb7ed9c1f6334853c
Author: Jonathan Wakely <jwak...@redhat.com>
Date:   Thu Aug 25 17:30:25 2016 +0100

    Add new std::basic_string constructor (LWG 2583)
    
        * config/abi/pre/gnu.ver (GLIBCXX_3.4, GLIBCXX_3.4.21): Use more
        precise patterns for basic_string constructors.
        (GLIBCXX_3.4.23): Export new constructors.
        * doc/xml/manual/intro.xml: Document LWG 2583 status.
        * doc/html/*: Regenerate.
        * include/bits/basic_string.h [_GLIBCXX_USE_CXX11_ABI]
        (basic_string(const basic_string&, size_type, const Alloc&)): Add
        new constructor for LWG 2583.
        (basic_string(const basic_string&, size_type, size_type)): Remove
        default argument.
        [!_GLIBCXX_USE_CXX11_ABI]: Likewise.
        * include/bits/basic_string.tcc [!_GLIBCXX_USE_CXX11_ABI]: Define it.
        * testsuite/21_strings/basic_string/cons/char/8.cc: New test.
        * testsuite/21_strings/basic_string/cons/wchar_t/8.cc: New test.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver 
b/libstdc++-v3/config/abi/pre/gnu.ver
index f51c6f9..0ab4bb1 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -206,7 +206,14 @@ GLIBCXX_3.4 {
     # std::string
     # 'y' here and below represents 'unsigned long long'
     # where it is used for size_type on LLP64 platforms.
-    _ZNSsC[12][EI][PRjmvyN]*;
+    _ZNSsC[12]EPKc*;
+    _ZNSsC[12]ERKSaIcE;
+    _ZNSsC[12]ERKSs;
+#   _ZNSsC[12]ERKSs[jmy]RKSaIcE;
+    _ZNSsC[12]ERKSs[jmy][jmy]*;
+    _ZNSsC[12]E[jmy]cRKSaIcE;
+    _ZNSsC[12]Ev;
+    _ZNSsC[12]I[PN]*;
     _ZNSsD*;
     _ZNSs[0-58-9]a*;
     _ZNSs5beginEv;
@@ -267,7 +274,13 @@ GLIBCXX_3.4 {
     _ZNKSs4copyEPc[jmy][jmy];
 
     # std::wstring
-    _ZNSbIwSt11char_traitsIwESaIwEEC[12][EI][PRjmvyN]*;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]EPKw*;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS[12]_;
+#   _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_mRKS1_;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_[jmy][jmy]*;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]E[jmy]wRKS1_;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]Ev;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]I[PN]*;
     _ZNSbIwSt11char_traitsIwESaIwEED*;
     _ZNSbIwSt11char_traitsIwESaIwEE[0-58-9]a*;
     _ZNSbIwSt11char_traitsIwESaIwEE5beginEv;
@@ -1683,7 +1696,17 @@ GLIBCXX_3.4.21 {
     _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE12_M*;
     _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE1[3-9]*;
     _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[2-9]*;
-    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[CDaip]*;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EOS4_*;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]EPK*;
+    
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS[34]_;
+    
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_RKS3_;
+#   
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy]RKS3_;
+    
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy][jmy]*;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ESt16*;
+    
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]E[jmy][cw]RKS3_;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]Ev;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]I[PN]*;
+    _ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE[Daip]*;
     _ZNKSt7__cxx1112basic_string*;
 
     # operator+ for ABI-tagged std::basic_string
@@ -1919,6 +1942,11 @@ GLIBCXX_3.4.23 {
     # basic_string<C, T, A>::_Alloc_hider::_Alloc_hider(C*, A&&)
     
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EE12_Alloc_hiderC[12]EP[cw]OS3_;
 
+    # basic_string<C, T, A>::basic_string(const basic_string&, size_type, 
const A&)
+    
_ZNSt7__cxx1112basic_stringI[cw]St11char_traitsI[cw]ESaI[cw]EEC[12]ERKS4_[jmy]RKS3_;
+    _ZNSsC[12]ERKSs[jmy]RKSaIcE;
+    _ZNSbIwSt11char_traitsIwESaIwEEC[12]ERKS2_mRKS1_;
+
 } GLIBCXX_3.4.22;
 
 # Symbols in the support library (libsupc++) have their own tag.
diff --git a/libstdc++-v3/doc/xml/manual/intro.xml 
b/libstdc++-v3/doc/xml/manual/intro.xml
index ea4d1c5..d02306e 100644
--- a/libstdc++-v3/doc/xml/manual/intro.xml
+++ b/libstdc++-v3/doc/xml/manual/intro.xml
@@ -1058,6 +1058,13 @@ requirements of the license of GCC.
     <listitem><para>Divide by the object type.
     </para></listitem></varlistentry>
 
+    <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink"; 
xlink:href="../ext/lwg-defects.html#2583">2583</link>:
+       <emphasis>There is no way to supply an allocator for <code> 
basic_string(str, pos)</code>
+       </emphasis>
+    </term>
+    <listitem><para>Add new constructor
+    </para></listitem></varlistentry>
+
     <varlistentry><term><link xmlns:xlink="http://www.w3.org/1999/xlink"; 
xlink:href="../ext/lwg-defects.html#2684">2684</link>:
        <emphasis><code>priority_queue</code> lacking comparator typedef
        </emphasis>
diff --git a/libstdc++-v3/include/bits/basic_string.h 
b/libstdc++-v3/include/bits/basic_string.h
index 68cfc99..e823f13 100644
--- a/libstdc++-v3/include/bits/basic_string.h
+++ b/libstdc++-v3/include/bits/basic_string.h
@@ -417,16 +417,31 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
                    _Alloc_traits::_S_select_on_copy(__str._M_get_allocator()))
       { _M_construct(__str._M_data(), __str._M_data() + __str.length()); }
 
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2583. no way to supply an allocator for basic_string(str, pos)
       /**
        *  @brief  Construct string as copy of a substring.
        *  @param  __str  Source string.
        *  @param  __pos  Index of first character to copy from.
-       *  @param  __n  Number of characters to copy (default remainder).
+       *  @param  __a  Allocator to use.
        */
-      // _GLIBCXX_RESOLVE_LIB_DEFECTS
-      // 2402. [this constructor] shouldn't use Allocator()
       basic_string(const basic_string& __str, size_type __pos,
-                  size_type __n = npos)
+                  const _Alloc& __a = _Alloc())
+      : _M_dataplus(_M_local_data(), __a)
+      {
+       const _CharT* __start = __str._M_data()
+         + __str._M_check(__pos, "basic_string::basic_string");
+       _M_construct(__start, __start + __str._M_limit(__pos, npos));
+      }
+
+      /**
+       *  @brief  Construct string as copy of a substring.
+       *  @param  __str  Source string.
+       *  @param  __pos  Index of first character to copy from.
+       *  @param  __n  Number of characters to copy.
+       */
+      basic_string(const basic_string& __str, size_type __pos,
+                  size_type __n)
       : _M_dataplus(_M_local_data())
       {
        const _CharT* __start = __str._M_data()
@@ -438,7 +453,7 @@ _GLIBCXX_BEGIN_NAMESPACE_CXX11
        *  @brief  Construct string as copy of a substring.
        *  @param  __str  Source string.
        *  @param  __pos  Index of first character to copy from.
-       *  @param  __n  Number of characters to copy (default remainder).
+       *  @param  __n  Number of characters to copy.
        *  @param  __a  Allocator to use.
        */
       basic_string(const basic_string& __str, size_type __pos,
@@ -3305,14 +3320,26 @@ _GLIBCXX_END_NAMESPACE_CXX11
        *  @param  __str  Source string.
        */
       basic_string(const basic_string& __str);
+
+      // _GLIBCXX_RESOLVE_LIB_DEFECTS
+      // 2583. no way to supply an allocator for basic_string(str, pos)
       /**
        *  @brief  Construct string as copy of a substring.
        *  @param  __str  Source string.
        *  @param  __pos  Index of first character to copy from.
-       *  @param  __n  Number of characters to copy (default remainder).
+       *  @param  __a  Allocator to use.
        */
       basic_string(const basic_string& __str, size_type __pos,
-                  size_type __n = npos);
+                  const _Alloc& __a = _Alloc());
+
+      /**
+       *  @brief  Construct string as copy of a substring.
+       *  @param  __str  Source string.
+       *  @param  __pos  Index of first character to copy from.
+       *  @param  __n  Number of characters to copy.
+       */
+      basic_string(const basic_string& __str, size_type __pos,
+                  size_type __n);
       /**
        *  @brief  Construct string as copy of a substring.
        *  @param  __str  Source string.
diff --git a/libstdc++-v3/include/bits/basic_string.tcc 
b/libstdc++-v3/include/bits/basic_string.tcc
index 0560b46..0080d2b 100644
--- a/libstdc++-v3/include/bits/basic_string.tcc
+++ b/libstdc++-v3/include/bits/basic_string.tcc
@@ -621,6 +621,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   template<typename _CharT, typename _Traits, typename _Alloc>
     basic_string<_CharT, _Traits, _Alloc>::
+    basic_string(const basic_string& __str, size_type __pos, const _Alloc& __a)
+    : _M_dataplus(_S_construct(__str._M_data()
+                              + __str._M_check(__pos,
+                                               "basic_string::basic_string"),
+                              __str._M_data() + __str._M_limit(__pos, npos)
+                              + __pos, __a), __a)
+    { }
+
+  template<typename _CharT, typename _Traits, typename _Alloc>
+    basic_string<_CharT, _Traits, _Alloc>::
     basic_string(const basic_string& __str, size_type __pos, size_type __n)
     : _M_dataplus(_S_construct(__str._M_data()
                               + __str._M_check(__pos,
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc 
b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc
new file mode 100644
index 0000000..6534f76
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/char/8.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
+// any later version.
+
+// This library 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 library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+template<typename... Args>
+std::size_t
+construct(Args&&... args)
+{
+  return std::string( std::forward<Args>(args)... ).length();
+}
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  using string = std::string;
+  using list = std::initializer_list<string::value_type>;
+
+  const std::string lvalue = "lvalue";
+  std::allocator<char> alloc;
+
+  // test all valid combinations of arguments:
+  VERIFY( construct( ) == 0 );
+  VERIFY( construct( alloc ) == 0 );
+  VERIFY( construct( lvalue ) == 6 );
+  VERIFY( construct( string{"rvalue"} ) == 6 );
+  VERIFY( construct( lvalue, 2 ) == 4 );
+  VERIFY( construct( lvalue, 2, alloc ) == 4 );
+  VERIFY( construct( lvalue, 2, 3 ) == 3 );
+  VERIFY( construct( lvalue, 2, 3, alloc ) == 3 );
+  VERIFY( construct( "C string", 4 ) == 4 );
+  VERIFY( construct( "C string", 4, alloc ) == 4 );
+  VERIFY( construct( "C string" ) == 8 );
+  VERIFY( construct( "C string and alloc", alloc ) == 18 );
+  VERIFY( construct( 5, ' ' ) == 5 );
+  VERIFY( construct( 5, ' ', alloc ) == 5 );
+  VERIFY( construct( lvalue.begin(), lvalue.end() ) == 6 );
+  VERIFY( construct( lvalue.begin(), lvalue.end(), alloc ) == 6 );
+  VERIFY( construct( list{ 'l' , 'i' , 's', 't' } ) == 4 );
+  VERIFY( construct( list{ 'l', 'i', 's', 't' }, alloc ) == 4 );
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( construct( lvalue, alloc ) == 6 );
+  VERIFY( construct( string{"rvalue"}, alloc ) == 6 );
+#endif
+}
+
+int
+main()
+{
+  test01();
+}
diff --git a/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc 
b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc
new file mode 100644
index 0000000..9152ad9
--- /dev/null
+++ b/libstdc++-v3/testsuite/21_strings/basic_string/cons/wchar_t/8.cc
@@ -0,0 +1,70 @@
+// Copyright (C) 2016 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library 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, or (at your option)
+// any later version.
+
+// This library 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 library; see the file COPYING3.  If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+
+#include <string>
+#include <testsuite_hooks.h>
+
+template<typename... Args>
+std::size_t
+construct(Args&&... args)
+{
+  return std::wstring( std::forward<Args>(args)... ).length();
+}
+
+void
+test01()
+{
+  bool test __attribute__((unused)) = true;
+
+  using string = std::wstring;
+  using list = std::initializer_list<string::value_type>;
+
+  const std::wstring lvalue = L"lvalue";
+  std::allocator<char> alloc;
+
+  // test all valid combinations of arguments:
+  VERIFY( construct( ) == 0 );
+  VERIFY( construct( alloc ) == 0 );
+  VERIFY( construct( lvalue ) == 6 );
+  VERIFY( construct( string{L"rvalue"} ) == 6 );
+  VERIFY( construct( lvalue, 2 ) == 4 );
+  VERIFY( construct( lvalue, 2, alloc ) == 4 );
+  VERIFY( construct( lvalue, 2, 3 ) == 3 );
+  VERIFY( construct( lvalue, 2, 3, alloc ) == 3 );
+  VERIFY( construct( L"C string", 4 ) == 4 );
+  VERIFY( construct( L"C string", 4, alloc ) == 4 );
+  VERIFY( construct( L"C string" ) == 8 );
+  VERIFY( construct( L"C string and alloc", alloc ) == 18 );
+  VERIFY( construct( 5, L' ' ) == 5 );
+  VERIFY( construct( 5, L' ', alloc ) == 5 );
+  VERIFY( construct( lvalue.begin(), lvalue.end() ) == 6 );
+  VERIFY( construct( lvalue.begin(), lvalue.end(), alloc ) == 6 );
+  VERIFY( construct( list{ L'l' , L'i' , L's', L't' } ) == 4 );
+  VERIFY( construct( list{ L'l', L'i', L's', L't' }, alloc ) == 4 );
+#if _GLIBCXX_USE_CXX11_ABI
+  VERIFY( construct( lvalue, alloc ) == 6 );
+  VERIFY( construct( string{L"rvalue"}, alloc ) == 6 );
+#endif
+}
+
+int
+main()
+{
+  test01();
+}
#!/usr/bin/python

from __future__ import print_function
import sys
import fnmatch
import subprocess
import argparse

GLOB, DEMANGLED = 1, 2

def read_patterns(filename):
        """Read a linker script into a dictionary.

        Returns { "VER_1": {N: ("foo*", T), N:("bar[ij]", T)} }
        where N is the line number of the pattern
        and T is a bitmask of the elements GLOB and DEMANGLED.
        """
        with open(filename) as f:
                INIT, VERSION, EXTERN_CXX = range(3)
                patterns = {}
                filename = filename.split('/')[-1]
                state = INIT
                ver = None
                local = False
                for n, line in enumerate(f):
                        # trim comments
                        line = line.partition('#')[0].strip()
                        # skip blank lines
                        if not line:
                                continue
                        n += 1
                        if state == INIT:
                                if line[-1] != '{':
                                        raise ValueError("{0}:{1}: Invalid 
characters at global scope: {2}".format(filename, n, line))
                                ver = line[0:-1].rstrip()
                                state = VERSION
                                local = False
                                continue
                        elif state == VERSION:
                                if line == "global:":
                                        continue
                                elif line == "local:":
                                        local = True
                                        continue
                                if line == 'extern "C++"':
                                        state = EXTERN_CXX
                                        continue
                                if line[0] == '}' and line[-1] == ';':
                                        state = INIT
                                        continue
                        elif state == EXTERN_CXX:
                                if line == '{':
                                        continue
                                elif line == '};':
                                        state = VERSION
                                        continue

                        if line[-1] != ';':
                                # TODO allow trailing semi-colon to be omitted 
at end of node
                                raise ValueError("{0}:{1}: Invalid pattern: 
{2}".format(filename, n, line))

                        if local:
                                continue

                        pattern = line[0:-1]
                        pattern_type = 0
                        if state == EXTERN_CXX:
                                pattern_type |= DEMANGLED
                        if pattern[0] == '"' and pattern[-1] == '"':
                                pattern = pattern[1:-1]
                        else:
                                pattern_type |= GLOB
                        patterns.setdefault(ver, {})[n] = (pattern, 
pattern_type)

                if state != INIT:
                        raise ValueError("{0}: incomplete node: 
{1}".format(filename, ver))

                return patterns

class Demangler:
        def __enter__(self):
                self.child = subprocess.Popen(['c++filt'], 
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
                return self

        def __exit__(self, exc_type, exc_value, traceback):
                self.child.stdin.close()

        def __call__(self, mangled):
                """Demangle a symbol name."""
                self.child.stdin.write((mangled+'\n').encode())
                self.child.stdin.flush()
                return self.child.stdout.readline().decode().rstrip('\n')

def find_matches(symbols, patterns, verbose, full, conflicts = False):
        """For each symbol name find which patterns it matches.

        Return a list of symbols and the patterns they match.

        When the optional argument conflicts is True only match symbols
        that match patterns in more than one version.
        """
        with Demangler() as demangle:
                res = []
                count = 0
                for symbol in symbols:
                        demangled = demangle(symbol)

                        matches = {}

                        for v, ps in iter(patterns.items()):
                                for n, (p, t) in iter(ps.items()):
                                        if t & DEMANGLED:
                                                s = demangled
                                        else:
                                                s = symbol
                                        # Python fnmatch uses [!abc] not [^abc]
                                        p = p.replace('[^', '[!')
                                        if fnmatch.fnmatch(s, p):
                                                matches.setdefault(v, 
[]).append(n)
                                                if not full:
                                                        break

                        if symbol == demangled:
                                demangled = None

                        if conflicts:
                                if len(matches) > 1:
                                        res.append( (symbol, demangled, 
matches) )
                                        if verbose:
                                                sys.stdout.write('!')
                                                sys.stdout.flush()
                        else:
                                res.append( (symbol, demangled, matches) )

                        if verbose:
                                count += 1
                                if not (count % 10):
                                        sys.stdout.write('#')
                                        sys.stdout.flush()
                if verbose:
                        sys.stdout.write('\n')

                return res


def show_matches(all_matches, patterns, conflicts):
        for symbol, demangled, matches in all_matches:
                if len(matches) == 0:
                        continue
                if conflicts:
                        print("Symbol matches more than one version:")
                else:
                        print("Symbol matches:")
                print(symbol)
                if demangled:
                        print(demangled)
                for v, ms in iter(matches.items()):
                        for m in ms:
                                p = patterns[v][m][0]
                                print("  {0:<18} {1} (line {2})".format(v, p, 
m))
                else:
                        print('')

def main():
        parser = argparse.ArgumentParser(description='Read symbols from 
standard input and match against patterns in a linker script.')
        parser.add_argument('script', metavar='linker-script', help='linker 
version script')
        parser.add_argument('-c', '--conflicts', action = 'store_true', 
help='check for symbols that match multiple patterns')
        parser.add_argument('-u', '--unmatched', action = 'store_true', 
help='check for symbols that match no patterns')
        parser.add_argument('-f', '--full', action = 'store_true', help='check 
all patterns for a version (default: only report first match per version)')
        parser.add_argument('-v', '--verbose', action = 'store_true', 
help='show progress indicator every ten symbols processed')

        args = parser.parse_args()

        patterns = read_patterns(args.script)
        symbols = [line.strip() for line in sys.stdin]
        matches = find_matches(symbols, patterns, args.verbose, args.full and 
not args.unmatched, args.conflicts)

        if args.unmatched:
                for symbol in [s for s, _, m in matches if len(m) == 0]:
                        print(symbol)
        else:
                show_matches(matches, patterns, args.conflicts)

if __name__ == "__main__": main()

Reply via email to