It's been pointed out to me that if we merge db's with the obvious
(find . -name 'temp-*.db' | xargs gcj-dbtool -m $DB)
we run the risk of failure if arg length exceeds the operating system
limit, because xargs will call gcj-dbtool several times.
The right way to fix this is to have gcj-dbtool read a list of files
from stdin, which is what this patch does.
(find . -name 'temp-*.db' | gcj-dbtool - -m $DB)
Andrew.
2005-03-30 Andrew Haley <aph(a)redhat.com>
* gnu/gcj/tools/gcj_dbtool/Main.java (Fileset): New class.
(getFiles): New method.
(main): Add "-" argument.
Read list of files from stdin when merging map databases.
(usage): Add "-" argument.
Minor corrections.
Index: Main.java
===================================================================
RCS file: /cvs/gcc/gcc/libjava/gnu/gcj/tools/gcj_dbtool/Main.java,v
retrieving revision 1.9
diff -c -2 -p -r1.9 Main.java
*** Main.java 25 Mar 2005 00:38:43 -0000 1.9
--- Main.java 30 Mar 2005 15:04:15 -0000
*************** public class Main
*** 23,27 ****
--- 23,37 ----
public static void main (String[] s)
{
+ boolean fileListFromStdin = false;
insist (s.length >= 1);
+
+ if (s[0].equals("-"))
+ {
+ fileListFromStdin = true;
+ String[] newArgs = new String[s.length - 1];
+ System.arraycopy(s, 1, newArgs, 0, s.length - 1);
+ s = newArgs;
+ }
+
if (s[0].equals("-v") || s[0].equals("--version"))
{
*************** public class Main
*** 146,151 ****
{
// Merge databases.
! insist (s.length >= 3);
! try
{
File database = new File(s[1]);
--- 156,162 ----
{
// Merge databases.
! insist (s.length >= 3
! || fileListFromStdin && s.length == 2);
! try
{
File database = new File(s[1]);
*************** public class Main
*** 156,171 ****
int newSize = 0;
int newStringTableSize = 0;
! PersistentByteMap[] sourceMaps = new PersistentByteMap[s.length - 2];
// Scan all the input files, calculating worst case string
// table and hash table use.
! for (int i = 2; i < s.length; i++)
! {
! PersistentByteMap b
! = new PersistentByteMap(new File(s[i]),
! PersistentByteMap.AccessMode.READ_ONLY);
! newSize += b.size();
! newStringTableSize += b.stringTableSize();
! sourceMaps[i - 2] = b;
! }
newSize *= 1.5; // Scaling the new size by 1.5 results in
--- 167,188 ----
int newSize = 0;
int newStringTableSize = 0;
! Fileset files = getFiles(s, 2, fileListFromStdin);
! PersistentByteMap[] sourceMaps = new PersistentByteMap[files.size()];
!
// Scan all the input files, calculating worst case string
// table and hash table use.
! {
! Iterator it = files.iterator();
! int i = 0;
! while (it.hasNext())
! {
! PersistentByteMap b
! = new PersistentByteMap((File)it.next(),
! PersistentByteMap.AccessMode.READ_ONLY);
! newSize += b.size();
! newStringTableSize += b.stringTableSize();
! sourceMaps[i++] = b;
! }
! }
newSize *= 1.5; // Scaling the new size by 1.5 results in
*************** public class Main
*** 297,310 ****
+ " gcj-dbtool -n file.gcjdb [size] - Create a new gcj map
database\n"
+ " gcj-dbtool -a file.gcjdb file.jar file.so\n"
! + " - Add the contents of file.jar to a new gcj map
database\n"
+ " gcj-dbtool -f file.gcjdb file.jar file.so\n"
! + " - Add the contents of file.jar to a new gcj map
database\n"
+ " gcj-dbtool -t file.gcjdb - Test a gcj map
database\n"
+ " gcj-dbtool -l file.gcjdb - List a gcj map
database\n"
! + " gcj-dbtool -m dest.gcjdb [source.gcjdb]...\n"
! + " - Merge gcj map databases into dest\n"
! + " Replaces dest\n"
! + " To add to dest, include dest in the list of
sources\n"
! + " gcj-dbtool -p [LIBDIR] - Print default database
name");
}
--- 314,329 ----
+ " gcj-dbtool -n file.gcjdb [size] - Create a new gcj map
database\n"
+ " gcj-dbtool -a file.gcjdb file.jar file.so\n"
! + " - Add the contents of file.jar to a gcj map database\n"
+ " gcj-dbtool -f file.gcjdb file.jar file.so\n"
! + " - Add the contents of file.jar to a gcj map database\n"
+ " gcj-dbtool -t file.gcjdb - Test a gcj map
database\n"
+ " gcj-dbtool -l file.gcjdb - List a gcj map
database\n"
! + " gcj-dbtool [-] -m dest.gcjdb [source.gcjdb]...\n"
! + " - Merge gcj map databases into dest\n"
! + " Replaces dest\n"
! + " To add to dest, include dest in the list of
sources\n"
! + " If the first arg is -, read the list from stdin\n"
! + " gcj-dbtool -p [LIBDIR] - Print default database
name"
! );
}
*************** public class Main
*** 406,409 ****
--- 425,485 ----
return hexBytes.toString();
}
+
+
+ // Return a Fileset, either from a String array or from System.in,
+ // depending on fileListFromStdin.
+ private static final Fileset getFiles(String[] s, int startPos,
+ boolean fileListFromStdin)
+ {
+ if (fileListFromStdin)
+ return new Fileset(System.in);
+ else
+ return new Fileset(s, startPos, s.length);
+ }
}
+ // A Fileset is a container for a set of files; it can be created
+ // either from a string array or from an input stream.
+ class Fileset
+ {
+ LinkedHashSet files = new LinkedHashSet();
+
+ Fileset (String[] s, int start, int end)
+ {
+ for (int i = start; i < end; i++)
+ {
+ files.add(new File(s[i]));
+ }
+ }
+
+ Fileset (InputStream is)
+ {
+ Reader r = new BufferedReader(new InputStreamReader(is));
+ StringBuffer buf = new StringBuffer();
+ try
+ {
+ int chr;
+ while ((chr = r.read()) != -1)
+ buf.append((char)chr);
+ }
+ catch (IOException _)
+ {
+ }
+ StringTokenizer st = new StringTokenizer(buf.toString());
+ while (st.hasMoreElements ())
+ {
+ String name = st.nextToken ();
+ files.add(new File(name));
+ }
+ }
+
+ Iterator iterator()
+ {
+ return files.iterator();
+ }
+
+ int size()
+ {
+ return files.size();
+ }
+ }