mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-05 13:35:32 +00:00
ICU-21757 Stop sharing utilities-for-cldr
Moves UnicodeMap and related classes to core. Also removes `CollectionUtilities`, `UOption`, and `ElapsedTimer`. They will end up in UnicodeTools, CLDR, and CLDR respectively.
This commit is contained in:
parent
c92c188cac
commit
9369b7a209
17 changed files with 24 additions and 1324 deletions
25
.github/workflows/maven.yaml
vendored
25
.github/workflows/maven.yaml
vendored
|
@ -35,8 +35,8 @@ jobs:
|
|||
version="`mvn help:evaluate -Dexpression=project.version -q -DforceStdout`"
|
||||
echo "version=$version" # debug/info logging for our own purposes, before sending to Github
|
||||
echo "version=$version" >> "$GITHUB_OUTPUT"
|
||||
# Set version-type=snapshot for tags that contain SNAPSHOT,
|
||||
# as well as for unicode-org-internal artifacts with a dash like `icu4j-for-cldr`.
|
||||
# Set version-type=snapshot for tags that contain SNAPSHOT,
|
||||
# as well as for unicode-org-internal artifacts with a dash like `icu4j-for-cldr`.
|
||||
- name: Assess Maven version release/snapshot
|
||||
id: mvn-proj-version-type
|
||||
run: |
|
||||
|
@ -49,33 +49,18 @@ jobs:
|
|||
run: |
|
||||
echo "Manual deployments of publishing artifacts should only be attempted for snapshot versions"
|
||||
exit 1;
|
||||
- name: Build artifacts (icu4j, utilities-for-cldr)
|
||||
- name: Build artifacts (icu4j)
|
||||
run: |
|
||||
cd icu4j
|
||||
mvn ${SHARED_MVN_ARGS} clean install -DskipTests -DskipIT -P with_sources
|
||||
# For snapshot versions, publish icu4j & utilities-for-cldr
|
||||
# For snapshot versions, publish icu4j
|
||||
- name: Deploy to Github (snapshot version)
|
||||
if: steps.mvn-proj-version-type.outputs.version-type == 'snapshot'
|
||||
run: |
|
||||
echo Github Ref ${GITHUB_REF} @ ${GITHUB_SHA};
|
||||
cd icu4j
|
||||
mvn deploy ${SHARED_MVN_ARGS} \
|
||||
-pl :icu4j,:utilities-for-cldr,:icu4j-root \
|
||||
-DaltDeploymentRepository=github::https://maven.pkg.github.com/${GITHUB_REPOSITORY} \
|
||||
-P cldr_utilities,with_sources
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
# For release versions, publish utilities-for-cldr,
|
||||
# but do not publish icu4j because the Maven artifact "coordinates"
|
||||
# will conflict with the public-facing coordinates on Maven Central
|
||||
# ("coordinates" = groupId, artifactId, version)
|
||||
- name: Deploy to Github (release version)
|
||||
if: steps.mvn-proj-version-type.outputs.version-type == 'release'
|
||||
run: |
|
||||
echo Github Ref ${GITHUB_REF} @ ${GITHUB_SHA};
|
||||
cd icu4j
|
||||
mvn deploy ${SHARED_MVN_ARGS} \
|
||||
-pl :utilities-for-cldr,:icu4j-root \
|
||||
-pl :icu4j,:icu4j-root \
|
||||
-DaltDeploymentRepository=github::https://maven.pkg.github.com/${GITHUB_REPOSITORY} \
|
||||
-P cldr_utilities,with_sources
|
||||
env:
|
||||
|
|
|
@ -102,10 +102,6 @@ To import into IntelliJ:
|
|||
Navigating the source code files between main code and test code, and running tests individually or for an entire module,
|
||||
work as they do normally in IntelliJ.
|
||||
|
||||
> :point_right: **Note**: Currently, Maven cannot build the entire project due to settings for `tools/utilities-for-cldr`. To work around this so that `Build > Build Project` works: in the "Project" toolbar, navigate to the `tools/utilities-for-cldr` folder, right click for the contextual menu, then `Maven > Ignore Projects`.
|
||||
>
|
||||
> When this workaround is no longer needed, the project can be reenabled by: `View > Tool Windows > Maven`, then expand "International Components for Unicode (ICU)", right click on `utilities-for-cldr`, then select `Unignore Projects`.
|
||||
|
||||
### Eclipse
|
||||
|
||||
[Eclipse's Maven plugin](https://eclipse.dev/m2e/)
|
||||
|
|
|
@ -288,11 +288,10 @@ Once the JDK and Maven are installed, run the desired Maven target. For example:
|
|||
[INFO] demos [jar]
|
||||
[INFO] samples [jar]
|
||||
[INFO] tools_misc [jar]
|
||||
[INFO] utilities-for-cldr [jar]
|
||||
[INFO] perf-tests [jar]
|
||||
[INFO]
|
||||
[INFO] -----------------------< com.ibm.icu:icu4j-root >-----------------------
|
||||
[INFO] Building International Components for Unicode for Java (icu4j-root) 74.1-SNAPSHOT [1/17]
|
||||
[INFO] Building International Components for Unicode for Java (icu4j-root) 74.1-SNAPSHOT [1/16]
|
||||
[INFO] --------------------------------[ pom ]---------------------------------
|
||||
[INFO]
|
||||
[INFO] --- maven-enforcer-plugin:3.3.0:enforce (enforce-maven) @ icu4j-root ---
|
||||
|
@ -320,12 +319,11 @@ Once the JDK and Maven are installed, run the desired Maven target. For example:
|
|||
[INFO] demos .............................................. SUCCESS [ 0.111 s]
|
||||
[INFO] samples ............................................ SUCCESS [ 0.076 s]
|
||||
[INFO] tools_misc ......................................... SUCCESS [ 0.079 s]
|
||||
[INFO] utilities-for-cldr ................................. SUCCESS [ 1.284 s]
|
||||
[INFO] perf-tests ......................................... SUCCESS [ 0.128 s]
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] BUILD SUCCESS
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
[INFO] Total time: 04:16 min
|
||||
[INFO] Total time: 04:15 min
|
||||
[INFO] Finished at: 2023-10-03T16:16:06-07:00
|
||||
[INFO] ------------------------------------------------------------------------
|
||||
~~~
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.util;
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Map;
|
||||
|
|
@ -6,7 +6,7 @@
|
|||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.util;
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
|
@ -6,7 +6,7 @@
|
|||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.util;
|
||||
package com.ibm.icu.impl;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
|
@ -6,14 +6,13 @@
|
|||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.translit;
|
||||
package com.ibm.icu.dev.test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import com.ibm.icu.dev.test.TestBoilerplate;
|
||||
import com.ibm.icu.dev.util.UnicodeMap;
|
||||
import com.ibm.icu.impl.UnicodeMap;
|
||||
|
||||
/**
|
||||
* Moved from UnicodeMapTest
|
|
@ -6,7 +6,7 @@
|
|||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.translit;
|
||||
package com.ibm.icu.dev.test;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
|
@ -26,11 +26,8 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import com.ibm.icu.dev.test.TestBoilerplate;
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.dev.util.UnicodeMap;
|
||||
import com.ibm.icu.dev.util.UnicodeMap.EntryRange;
|
||||
import com.ibm.icu.dev.util.UnicodeMapIterator;
|
||||
import com.ibm.icu.impl.UnicodeMap;
|
||||
import com.ibm.icu.impl.UnicodeMapIterator;
|
||||
import com.ibm.icu.impl.Utility;
|
||||
import com.ibm.icu.lang.UCharacter;
|
||||
import com.ibm.icu.lang.UProperty;
|
||||
|
@ -59,7 +56,7 @@ public class UnicodeMapTest extends TestFmwk {
|
|||
checkToString(foo, "0003=6.0\n0005=10.0\n10FFFF=666.0\n006E,0065,0067=-555.0\n");
|
||||
|
||||
double i = 0;
|
||||
for (EntryRange<Double> entryRange : foo.entryRanges()) {
|
||||
for (UnicodeMap.EntryRange<Double> entryRange : foo.entryRanges()) {
|
||||
i += entryRange.value;
|
||||
}
|
||||
assertEquals("EntryRange<T>", 127d, i);
|
||||
|
@ -67,7 +64,7 @@ public class UnicodeMapTest extends TestFmwk {
|
|||
|
||||
public void checkToString(UnicodeMap<Double> foo, String expected) {
|
||||
StringJoiner joiner = new StringJoiner("\n");
|
||||
for (EntryRange range : foo.entryRanges()) {
|
||||
for (UnicodeMap.EntryRange range : foo.entryRanges()) {
|
||||
joiner.add(range.toString());
|
||||
}
|
||||
assertEquals("EntryRange<T>", expected, joiner.toString() + (foo.size() == 0 ? "" : "\n"));
|
|
@ -6,7 +6,7 @@
|
|||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.translit;
|
||||
package com.ibm.icu.dev.test;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -1,631 +0,0 @@
|
|||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2015, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.util;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
/**
|
||||
* Utilities that ought to be on collections, but aren't
|
||||
*
|
||||
* @internal CLDR
|
||||
*/
|
||||
public final class CollectionUtilities {
|
||||
|
||||
/**
|
||||
* Join an array of items.
|
||||
* @param <T>
|
||||
* @param array
|
||||
* @param separator
|
||||
* @return string
|
||||
*/
|
||||
public static <T> String join(T[] array, String separator) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (i != 0) result.append(separator);
|
||||
result.append(array[i]);
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a collection of items.
|
||||
* @param <T>
|
||||
* @param collection
|
||||
* @param <U>
|
||||
* @param array
|
||||
* @param separator
|
||||
* @return string
|
||||
*/
|
||||
public static <T, U extends Iterable<T>>String join(U collection, String separator) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
boolean first = true;
|
||||
for (Iterator it = collection.iterator(); it.hasNext();) {
|
||||
if (first) first = false;
|
||||
else result.append(separator);
|
||||
result.append(it.next());
|
||||
}
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility like Arrays.asList()
|
||||
* @param source
|
||||
* @param target
|
||||
* @param reverse
|
||||
* @param <T>
|
||||
* @return
|
||||
*/
|
||||
public static <T> Map<T,T> asMap(T[][] source, Map<T,T> target, boolean reverse) {
|
||||
int from = 0, to = 1;
|
||||
if (reverse) {
|
||||
from = 1; to = 0;
|
||||
}
|
||||
for (int i = 0; i < source.length; ++i) {
|
||||
target.put(source[i][from], source[i][to]);
|
||||
}
|
||||
return target;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add all items in iterator to target collection
|
||||
* @param <T>
|
||||
* @param <U>
|
||||
* @param source
|
||||
* @param target
|
||||
* @return
|
||||
*/
|
||||
public static <T, U extends Collection<T>> U addAll(Iterator<T> source, U target) {
|
||||
while (source.hasNext()) {
|
||||
target.add(source.next());
|
||||
}
|
||||
return target; // for chaining
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the size of an iterator (number of items in it).
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static int size(Iterator source) {
|
||||
int result = 0;
|
||||
while (source.hasNext()) {
|
||||
source.next();
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param <T>
|
||||
* @param source
|
||||
* @return
|
||||
*/
|
||||
public static <T> Map<T,T> asMap(T[][] source) {
|
||||
return asMap(source, new HashMap<T,T>(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility that ought to be on Map
|
||||
* @param m
|
||||
* @param itemsToRemove
|
||||
* @param <K>
|
||||
* @param <V>
|
||||
* @return map passed in
|
||||
*/
|
||||
public static <K,V> Map<K,V> removeAll(Map<K,V> m, Collection<K> itemsToRemove) {
|
||||
for (Iterator it = itemsToRemove.iterator(); it.hasNext();) {
|
||||
Object item = it.next();
|
||||
m.remove(item);
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get first item in collection, or null if there is none.
|
||||
* @param <T>
|
||||
* @param <U>
|
||||
* @param c
|
||||
* @return first item
|
||||
*/
|
||||
public <T, U extends Collection<T>> T getFirst(U c) {
|
||||
Iterator<T> it = c.iterator();
|
||||
if (!it.hasNext()) return null;
|
||||
return it.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the "best" in collection. That is the least if direction is < 0, otherwise the greatest. The first is chosen if there are multiples.
|
||||
* @param <T>
|
||||
* @param <U>
|
||||
* @param c
|
||||
* @param comp
|
||||
* @param direction
|
||||
* @return
|
||||
*/
|
||||
public static <T, U extends Collection<T>> T getBest(U c, Comparator<T> comp, int direction) {
|
||||
Iterator<T> it = c.iterator();
|
||||
if (!it.hasNext()) return null;
|
||||
T bestSoFar = it.next();
|
||||
if (direction < 0) {
|
||||
while (it.hasNext()) {
|
||||
T item = it.next();
|
||||
int compValue = comp.compare(item, bestSoFar);
|
||||
if (compValue < 0) {
|
||||
bestSoFar = item;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (it.hasNext()) {
|
||||
T item = it.next();
|
||||
int compValue = comp.compare(item, bestSoFar);
|
||||
if (compValue > 0) {
|
||||
bestSoFar = item;
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestSoFar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches item.
|
||||
* @param <T>
|
||||
*/
|
||||
public interface ObjectMatcher<T> {
|
||||
/**
|
||||
* Must handle null, never throw exception
|
||||
* @param o
|
||||
* @return
|
||||
*/
|
||||
boolean matches(T o);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse a match
|
||||
* @param <T>
|
||||
*/
|
||||
public static class InverseMatcher<T> implements ObjectMatcher<T> {
|
||||
ObjectMatcher<T> other;
|
||||
/**
|
||||
* @param toInverse
|
||||
* @return
|
||||
*/
|
||||
public ObjectMatcher set(ObjectMatcher toInverse) {
|
||||
other = toInverse;
|
||||
return this;
|
||||
}
|
||||
public boolean matches(T value) {
|
||||
return !other.matches(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove matching items
|
||||
* @param <T>
|
||||
* @param <U>
|
||||
* @param c
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static <T, U extends Collection<T>> U removeAll(U c, ObjectMatcher<T> f) {
|
||||
for (Iterator<T> it = c.iterator(); it.hasNext();) {
|
||||
T item = it.next();
|
||||
if (f.matches(item)) it.remove();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retain matching items
|
||||
* @param <T>
|
||||
* @param <U>
|
||||
* @param c
|
||||
* @param f
|
||||
* @return
|
||||
*/
|
||||
public static <T, U extends Collection<T>> U retainAll(U c, ObjectMatcher<T> f) {
|
||||
for (Iterator<T> it = c.iterator(); it.hasNext();) {
|
||||
T item = it.next();
|
||||
if (!f.matches(item)) it.remove();
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static boolean containsSome(Collection a, Collection b) {
|
||||
// fast paths
|
||||
if (a.size() == 0 || b.size() == 0) return false;
|
||||
if (a == b) return true; // must test after size test.
|
||||
|
||||
if (a instanceof SortedSet && b instanceof SortedSet) {
|
||||
SortedSet aa = (SortedSet) a;
|
||||
SortedSet bb = (SortedSet) b;
|
||||
Comparator bbc = bb.comparator();
|
||||
Comparator aac = aa.comparator();
|
||||
if (bbc == null && aac == null) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
|
||||
Comparable bo = (Comparable) bi.next();
|
||||
while (true) {
|
||||
int rel = ao.compareTo(bo);
|
||||
if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = (Comparable) ai.next();
|
||||
} else if (rel > 0) {
|
||||
if (!bi.hasNext()) return false;
|
||||
bo = (Comparable) bi.next();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if (bbc.equals(a)) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Object ao = ai.next(); // these are ok, since the sizes are != 0
|
||||
Object bo = bi.next();
|
||||
while (true) {
|
||||
int rel = aac.compare(ao, bo);
|
||||
if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = ai.next();
|
||||
} else if (rel > 0) {
|
||||
if (!bi.hasNext()) return false;
|
||||
bo = bi.next();
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator it = a.iterator(); it.hasNext();) {
|
||||
if (b.contains(it.next())) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean containsAll(Collection a, Collection b) {
|
||||
// fast paths
|
||||
if (a == b) return true;
|
||||
if (b.size() == 0) return true;
|
||||
if (a.size() < b.size()) return false;
|
||||
|
||||
if (a instanceof SortedSet && b instanceof SortedSet) {
|
||||
SortedSet aa = (SortedSet) a;
|
||||
SortedSet bb = (SortedSet) b;
|
||||
Comparator bbc = bb.comparator();
|
||||
Comparator aac = aa.comparator();
|
||||
if (bbc == null && aac == null) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Comparable ao = (Comparable) ai.next(); // these are ok, since the sizes are != 0
|
||||
Comparable bo = (Comparable) bi.next();
|
||||
while (true) {
|
||||
int rel = ao.compareTo(bo);
|
||||
if (rel == 0) {
|
||||
if (!bi.hasNext()) return true;
|
||||
if (!ai.hasNext()) return false;
|
||||
bo = (Comparable) bi.next();
|
||||
ao = (Comparable) ai.next();
|
||||
} else if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = (Comparable) ai.next();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (bbc.equals(aac)) {
|
||||
Iterator ai = aa.iterator();
|
||||
Iterator bi = bb.iterator();
|
||||
Object ao = ai.next(); // these are ok, since the sizes are != 0
|
||||
Object bo = bi.next();
|
||||
while (true) {
|
||||
int rel = aac.compare(ao, bo);
|
||||
if (rel == 0) {
|
||||
if (!bi.hasNext()) return true;
|
||||
if (!ai.hasNext()) return false;
|
||||
bo = bi.next();
|
||||
ao = ai.next();
|
||||
} else if (rel < 0) {
|
||||
if (!ai.hasNext()) return false;
|
||||
ao = ai.next();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return a.containsAll(b);
|
||||
}
|
||||
|
||||
public static boolean containsNone(Collection a, Collection b) {
|
||||
return !containsSome(a, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used for results of getContainmentRelation
|
||||
*/
|
||||
public static final int
|
||||
ALL_EMPTY = 0,
|
||||
NOT_A_SUPERSET_B = 1,
|
||||
NOT_A_DISJOINT_B = 2,
|
||||
NOT_A_SUBSET_B = 4,
|
||||
NOT_A_EQUALS_B = NOT_A_SUBSET_B | NOT_A_SUPERSET_B,
|
||||
A_PROPER_SUBSET_OF_B = NOT_A_DISJOINT_B | NOT_A_SUPERSET_B,
|
||||
A_PROPER_SUPERSET_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B,
|
||||
A_PROPER_OVERLAPS_B = NOT_A_SUBSET_B | NOT_A_DISJOINT_B | NOT_A_SUPERSET_B;
|
||||
|
||||
/**
|
||||
* Assesses all the possible containment relations between collections A and B with one call.<br>
|
||||
* Returns an int with bits set, according to a "Venn Diagram" view of A vs B.<br>
|
||||
* NOT_A_SUPERSET_B: a - b != {}<br>
|
||||
* NOT_A_DISJOINT_B: a * b != {} // * is intersects<br>
|
||||
* NOT_A_SUBSET_B: b - a != {}<br>
|
||||
* Thus the bits can be used to get the following relations:<br>
|
||||
* for A_SUPERSET_B, use (x & CollectionUtilities.NOT_A_SUPERSET_B) == 0<br>
|
||||
* for A_SUBSET_B, use (x & CollectionUtilities.NOT_A_SUBSET_B) == 0<br>
|
||||
* for A_EQUALS_B, use (x & CollectionUtilities.NOT_A_EQUALS_B) == 0<br>
|
||||
* for A_DISJOINT_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) == 0<br>
|
||||
* for A_OVERLAPS_B, use (x & CollectionUtilities.NOT_A_DISJOINT_B) != 0<br>
|
||||
*/
|
||||
public static int getContainmentRelation(Collection a, Collection b) {
|
||||
if (a.size() == 0) {
|
||||
return (b.size() == 0) ? ALL_EMPTY : NOT_A_SUPERSET_B;
|
||||
} else if (b.size() == 0) {
|
||||
return NOT_A_SUBSET_B;
|
||||
}
|
||||
int result = 0;
|
||||
// WARNING: one might think that the following can be short-circuited, by looking at
|
||||
// the sizes of a and b. However, this would fail in general, where a different comparator is being
|
||||
// used in the two collections. Unfortunately, there is no failsafe way to test for that.
|
||||
for (Iterator it = a.iterator(); result != 6 && it.hasNext();) {
|
||||
result |= (b.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUBSET_B;
|
||||
}
|
||||
for (Iterator it = b.iterator(); (result & 3) != 3 && it.hasNext();) {
|
||||
result |= (a.contains(it.next())) ? NOT_A_DISJOINT_B : NOT_A_SUPERSET_B;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does one string contain another, starting at a specific offset?
|
||||
* @param text
|
||||
* @param offset
|
||||
* @param other
|
||||
* @return
|
||||
*/
|
||||
public static int matchesAt(CharSequence text, int offset, CharSequence other) {
|
||||
int len = other.length();
|
||||
int i = 0;
|
||||
int j = offset;
|
||||
for (; i < len; ++i, ++j) {
|
||||
char pc = other.charAt(i);
|
||||
char tc = text.charAt(j);
|
||||
if (pc != tc) return -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* For producing filtered iterators
|
||||
*/
|
||||
public static abstract class FilteredIterator implements Iterator {
|
||||
private Iterator baseIterator;
|
||||
private static final Object EMPTY = new Object();
|
||||
private static final Object DONE = new Object();
|
||||
private Object nextObject = EMPTY;
|
||||
public FilteredIterator set(Iterator baseIterator) {
|
||||
this.baseIterator = baseIterator;
|
||||
return this;
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException("Doesn't support removal");
|
||||
}
|
||||
public Object next() {
|
||||
Object result = nextObject;
|
||||
nextObject = EMPTY;
|
||||
return result;
|
||||
}
|
||||
public boolean hasNext() {
|
||||
if (nextObject == DONE) return false;
|
||||
if (nextObject != EMPTY) return true;
|
||||
while (baseIterator.hasNext()) {
|
||||
nextObject = baseIterator.next();
|
||||
if (isIncluded(nextObject)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
nextObject = DONE;
|
||||
return false;
|
||||
}
|
||||
abstract public boolean isIncluded(Object item);
|
||||
}
|
||||
|
||||
public static class PrefixIterator extends FilteredIterator {
|
||||
private String prefix;
|
||||
public PrefixIterator set(Iterator baseIterator, String prefix) {
|
||||
super.set(baseIterator);
|
||||
this.prefix = prefix;
|
||||
return this;
|
||||
}
|
||||
public boolean isIncluded(Object item) {
|
||||
return ((String)item).startsWith(prefix);
|
||||
}
|
||||
}
|
||||
|
||||
public static class RegexIterator extends FilteredIterator {
|
||||
private Matcher matcher;
|
||||
public RegexIterator set(Iterator baseIterator, Matcher matcher) {
|
||||
super.set(baseIterator);
|
||||
this.matcher = matcher;
|
||||
return this;
|
||||
}
|
||||
public boolean isIncluded(Object item) {
|
||||
return matcher.reset((String)item).matches();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare, allowing nulls
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static <T> boolean equals(T a, T b) {
|
||||
return a == null
|
||||
? b == null
|
||||
: b == null ? false : a.equals(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare, allowing nulls and putting them first
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static <T extends Comparable> int compare(T a, T b) {
|
||||
return a == null
|
||||
? b == null ? 0 : -1
|
||||
: b == null ? 1 : a.compareTo(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare iterators
|
||||
* @param iterator1
|
||||
* @param iterator2
|
||||
* @return
|
||||
*/
|
||||
public static <T extends Comparable> int compare(Iterator<T> iterator1, Iterator<T> iterator2) {
|
||||
int diff;
|
||||
while (true) {
|
||||
if (!iterator1.hasNext()) {
|
||||
return iterator2.hasNext() ? -1 : 0;
|
||||
} else if (!iterator2.hasNext()) {
|
||||
return 1;
|
||||
}
|
||||
diff = CollectionUtilities.compare(iterator1.next(), iterator2.next());
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare, with shortest first, and otherwise lexicographically
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static <T extends Comparable, U extends Collection<T>> int compare(U o1, U o2) {
|
||||
int diff = o1.size() - o2.size();
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
Iterator<T> iterator1 = o1.iterator();
|
||||
Iterator<T> iterator2 = o2.iterator();
|
||||
return compare(iterator1, iterator2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare, with shortest first, and otherwise lexicographically
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static <T extends Comparable, U extends Set<T>> int compare(U o1, U o2) {
|
||||
int diff = o1.size() - o2.size();
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
Collection<T> x1 = SortedSet.class.isInstance(o1) ? o1 : new TreeSet<T>(o1);
|
||||
Collection<T> x2 = SortedSet.class.isInstance(o2) ? o2 : new TreeSet<T>(o2);
|
||||
return compare(x1, x2);
|
||||
}
|
||||
|
||||
public static class SetComparator<T extends Comparable>
|
||||
implements Comparator<Set<T>> {
|
||||
public int compare(Set<T> o1, Set<T> o2) {
|
||||
return CollectionUtilities.compare(o1, o2);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public static class CollectionComparator<T extends Comparable>
|
||||
implements Comparator<Collection<T>> {
|
||||
public int compare(Collection<T> o1, Collection<T> o2) {
|
||||
return CollectionUtilities.compare(o1, o2);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Compare, allowing nulls and putting them first
|
||||
* @param a
|
||||
* @param b
|
||||
* @return
|
||||
*/
|
||||
public static <K extends Comparable, V extends Comparable, T extends Entry<K, V>> int compare(T a, T b) {
|
||||
if (a == null) {
|
||||
return b == null ? 0 : -1;
|
||||
} else if (b == null) {
|
||||
return 1;
|
||||
}
|
||||
int diff = compare(a.getKey(), b.getKey());
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
return compare(a.getValue(), b.getValue());
|
||||
}
|
||||
|
||||
public static <K extends Comparable, V extends Comparable, T extends Entry<K, V>> int compareEntrySets(Collection<T> o1, Collection<T> o2) {
|
||||
int diff = o1.size() - o2.size();
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
Iterator<T> iterator1 = o1.iterator();
|
||||
Iterator<T> iterator2 = o2.iterator();
|
||||
while (true) {
|
||||
if (!iterator1.hasNext()) {
|
||||
return iterator2.hasNext() ? -1 : 0;
|
||||
} else if (!iterator2.hasNext()) {
|
||||
return 1;
|
||||
}
|
||||
T item1 = iterator1.next();
|
||||
T item2 = iterator2.next();
|
||||
diff = CollectionUtilities.compare(item1, item2);
|
||||
if (diff != 0) {
|
||||
return diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class MapComparator<K extends Comparable, V extends Comparable> implements Comparator<Map<K,V>> {
|
||||
public int compare(Map<K, V> o1, Map<K, V> o2) {
|
||||
return CollectionUtilities.compareEntrySets(o1.entrySet(), o2.entrySet());
|
||||
}
|
||||
};
|
||||
|
||||
public static class ComparableComparator<T extends Comparable> implements Comparator<T> {
|
||||
public int compare(T arg0, T arg1) {
|
||||
return CollectionUtilities.compare(arg0, arg1);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
|
||||
package com.ibm.icu.dev.test.translit;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.junit.AfterClass;
|
||||
|
@ -11,7 +13,6 @@ import org.junit.Test;
|
|||
import org.junit.runner.RunWith;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.dev.util.UnicodeMap;
|
||||
import com.ibm.icu.text.CanonicalIterator;
|
||||
import com.ibm.icu.text.Normalizer2;
|
||||
import com.ibm.icu.text.Transliterator;
|
||||
|
@ -58,8 +59,8 @@ public class TransliteratorDisorderedMarksTest extends TestFmwk {
|
|||
// logln("NFKD Source: " + nfkdSource.toPattern(false));
|
||||
// logln("NFKD Target: " + nfkdTarget.toPattern(false));
|
||||
|
||||
UnicodeMap<UnicodeSet> leadToTrail = new UnicodeMap();
|
||||
UnicodeMap<UnicodeSet> leadToSources = new UnicodeMap();
|
||||
Map<Integer, UnicodeSet> leadToTrail = new HashMap<>();
|
||||
Map<Integer, UnicodeSet> leadToSources = new HashMap<>();
|
||||
UnicodeSet nonStarters = new UnicodeSet("[:^ccc=0:]").freeze();
|
||||
CanonicalIterator can = new CanonicalIterator("");
|
||||
|
||||
|
@ -101,8 +102,8 @@ public class TransliteratorDisorderedMarksTest extends TestFmwk {
|
|||
}
|
||||
|
||||
|
||||
for (Entry<String, UnicodeSet> x : leadToSources.entrySet()) {
|
||||
String lead = x.getKey();
|
||||
for (Entry<Integer, UnicodeSet> x : leadToSources.entrySet()) {
|
||||
Integer lead = x.getKey();
|
||||
UnicodeSet sources = x.getValue();
|
||||
UnicodeSet trailSet = leadToTrail.get(lead);
|
||||
for (String source : sources) {
|
||||
|
|
|
@ -1,163 +0,0 @@
|
|||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 1996-2016, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.test.util;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
|
||||
import com.ibm.icu.dev.test.TestFmwk;
|
||||
import com.ibm.icu.dev.util.CollectionUtilities;
|
||||
|
||||
@RunWith(JUnit4.class)
|
||||
public class TestUtilities extends TestFmwk {
|
||||
@Test
|
||||
public void TestCollectionUtilitySpeed() {
|
||||
TreeSet ts1 = new TreeSet();
|
||||
TreeSet ts2 = new TreeSet();
|
||||
int size = 1000;
|
||||
int iterations = 1000;
|
||||
String prefix = "abc";
|
||||
String postfix = "nop";
|
||||
for (int i = 0; i < size; ++i) {
|
||||
ts1.add(prefix + String.valueOf(i) + postfix);
|
||||
ts2.add(prefix + String.valueOf(i) + postfix);
|
||||
}
|
||||
// warm up
|
||||
CollectionUtilities.containsAll(ts1, ts2);
|
||||
ts1.containsAll(ts2);
|
||||
|
||||
timeAndCompare(ts1, ts2, iterations, true, .75);
|
||||
// now different sets
|
||||
ts1.add("Able");
|
||||
timeAndCompare(ts1, ts2, iterations, true, .75);
|
||||
timeAndCompare(ts2, ts1, iterations*100, false, 1.05);
|
||||
}
|
||||
|
||||
private void timeAndCompare(TreeSet ts1, TreeSet ts2, int iterations, boolean expected, double factorOfStandard) {
|
||||
double utilityTimeSorted = timeUtilityContainsAll(iterations, ts1, ts2, expected)/(double)iterations;
|
||||
double standardTimeSorted = timeStandardContainsAll(iterations, ts1, ts2, expected)/(double)iterations;
|
||||
|
||||
if (utilityTimeSorted < standardTimeSorted*factorOfStandard) {
|
||||
logln("Sorted: Utility time (" + utilityTimeSorted + ") << Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");
|
||||
} else {
|
||||
/*errln*/logln("Sorted: Utility time (" + utilityTimeSorted + ") !<< Standard duration (" + standardTimeSorted + "); " + 100*(utilityTimeSorted/standardTimeSorted) + "%");
|
||||
}
|
||||
}
|
||||
|
||||
private long timeStandardContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {
|
||||
long standardTime;
|
||||
{
|
||||
long start, end;
|
||||
boolean temp = false;
|
||||
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
temp = hs1.containsAll(hs2);
|
||||
if (temp != expected) {
|
||||
errln("Bad result");
|
||||
}
|
||||
}
|
||||
end = System.currentTimeMillis();
|
||||
standardTime = end - start;
|
||||
}
|
||||
return standardTime;
|
||||
}
|
||||
|
||||
private long timeUtilityContainsAll(int iterations, Set hs1, Set hs2, boolean expected) {
|
||||
long utilityTime;
|
||||
{
|
||||
long start, end;
|
||||
boolean temp = false;
|
||||
start = System.currentTimeMillis();
|
||||
for (int i = 0; i < iterations; ++i) {
|
||||
temp = CollectionUtilities.containsAll(hs1, hs2);
|
||||
if (temp != expected) {
|
||||
errln("Bad result");
|
||||
}
|
||||
}
|
||||
end = System.currentTimeMillis();
|
||||
utilityTime = end - start;
|
||||
}
|
||||
return utilityTime;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void TestCollectionUtilities() {
|
||||
String[][] test = {{"a", "c", "e", "g", "h", "z"}, {"b", "d", "f", "h", "w"}, { "a", "b" }, { "a", "d" }, {"d"}, {}}; //
|
||||
int resultMask = 0;
|
||||
for (int i = 0; i < test.length; ++i) {
|
||||
Collection a = new TreeSet(Arrays.asList(test[i]));
|
||||
for (int j = 0; j < test.length; ++j) {
|
||||
Collection b = new TreeSet(Arrays.asList(test[j]));
|
||||
int relation = CollectionUtilities.getContainmentRelation(a, b);
|
||||
resultMask |= (1 << relation);
|
||||
switch (relation) {
|
||||
case CollectionUtilities.ALL_EMPTY:
|
||||
checkContainment(a.size() == 0 && b.size() == 0, a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.NOT_A_SUPERSET_B:
|
||||
checkContainment(a.size() == 0 && b.size() != 0, a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.NOT_A_DISJOINT_B:
|
||||
checkContainment(a.equals(b) && a.size() != 0, a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.NOT_A_SUBSET_B:
|
||||
checkContainment(a.size() != 0 && b.size() == 0, a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.A_PROPER_SUBSET_OF_B:
|
||||
checkContainment(b.containsAll(a) && !a.equals(b), a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.NOT_A_EQUALS_B:
|
||||
checkContainment(!CollectionUtilities.containsSome(a, b) && a.size() != 0 && b.size() != 0, a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.A_PROPER_SUPERSET_B:
|
||||
checkContainment(a.containsAll(b) && !a.equals(b), a, relation, b);
|
||||
break;
|
||||
case CollectionUtilities.A_PROPER_OVERLAPS_B:
|
||||
checkContainment(!b.containsAll(a) && !a.containsAll(b) && CollectionUtilities.containsSome(a, b), a, relation, b);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (resultMask != 0xFF) {
|
||||
String missing = "";
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if ((resultMask & (1 << i)) == 0) {
|
||||
if (missing.length() != 0) missing += ", ";
|
||||
missing += RelationName[i];
|
||||
}
|
||||
}
|
||||
errln("Not all ContainmentRelations checked: " + missing);
|
||||
}
|
||||
}
|
||||
|
||||
static final String[] RelationName = {"ALL_EMPTY",
|
||||
"NOT_A_SUPERSET_B",
|
||||
"NOT_A_DISJOINT_B",
|
||||
"NOT_A_SUBSET_B",
|
||||
"A_PROPER_SUBSET_OF_B",
|
||||
"A_PROPER_DISJOINT_B",
|
||||
"A_PROPER_SUPERSET_B",
|
||||
"A_PROPER_OVERLAPS_B"};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private void checkContainment(boolean c, Collection a, int relation, Collection b) {
|
||||
if (!c) {
|
||||
errln("Fails relation: " + a + " \t" + RelationName[relation] + " \t" + b);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
//
|
||||
// ElapsedTimer.java
|
||||
//
|
||||
// Created by Steven R. Loomis on 11/11/2005.
|
||||
// Copyright 2005-2012 IBM. All rights reserved.
|
||||
//
|
||||
|
||||
package com.ibm.icu.dev.util;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
import com.ibm.icu.text.MessageFormat;
|
||||
import com.ibm.icu.text.NumberFormat;
|
||||
import com.ibm.icu.text.RuleBasedNumberFormat;
|
||||
|
||||
|
||||
/**
|
||||
* Simple stopwatch timer.
|
||||
* Usage: { ElapsedTimer et = new ElapsedTimer();
|
||||
* do_some_stuff;
|
||||
* System.out.println("It took " + et + " to do stuff."); }
|
||||
*
|
||||
* Advanced: { ElapsedTimer et = new ElapsedTimer("Thing2's time: {0}"); // messageformat pattern
|
||||
* do_thing_2();
|
||||
* System.out.println(et.toString()); }
|
||||
*
|
||||
* More advanced: NumberFormat and/or MessageFormat can be provided in the constructor
|
||||
*
|
||||
* @internal CLDR
|
||||
*/
|
||||
public final class ElapsedTimer {
|
||||
|
||||
/**
|
||||
* Convenience method to print the elasped time (in milliseconds)
|
||||
*/
|
||||
public static String elapsedTime(long start, long end) {
|
||||
return diffTime(getFormat(), start, end);
|
||||
}
|
||||
|
||||
public static String elapsedTime(long start) {
|
||||
return diffTime(getFormat(), start, System.currentTimeMillis());
|
||||
}
|
||||
|
||||
// class
|
||||
|
||||
private long startTime = System.currentTimeMillis();
|
||||
private NumberFormat myDurationFormat = null;
|
||||
private MessageFormat myMsgFormat = null;
|
||||
|
||||
public ElapsedTimer() {
|
||||
}
|
||||
|
||||
public ElapsedTimer(MessageFormat aMsgFmt) {
|
||||
myMsgFormat = aMsgFmt;
|
||||
}
|
||||
|
||||
public ElapsedTimer(NumberFormat aNumFmt) {
|
||||
myDurationFormat = aNumFmt;
|
||||
}
|
||||
|
||||
public ElapsedTimer(MessageFormat aMsgFmt, NumberFormat aNumFmt) {
|
||||
myMsgFormat = aMsgFmt;
|
||||
myDurationFormat = aNumFmt;
|
||||
}
|
||||
|
||||
public ElapsedTimer(String pattern) {
|
||||
myMsgFormat = new MessageFormat(pattern);
|
||||
}
|
||||
|
||||
public ElapsedTimer(String pattern, NumberFormat aNumFmt) {
|
||||
myMsgFormat = new MessageFormat(pattern);
|
||||
myDurationFormat = aNumFmt;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return elapsed time in seconds since object creation
|
||||
*/
|
||||
public final String toString() {
|
||||
long endTime = System.currentTimeMillis();
|
||||
String duration = diffTime(myDurationFormat, startTime, endTime);
|
||||
if(myMsgFormat == null) {
|
||||
return duration;
|
||||
} else {
|
||||
return myMsgFormat.format(new Object[] {duration});
|
||||
}
|
||||
}
|
||||
|
||||
private static NumberFormat gFormat = null;
|
||||
|
||||
private static NumberFormat getFormat() {
|
||||
if(gFormat == null) {
|
||||
gFormat = new RuleBasedNumberFormat(Locale.US,
|
||||
RuleBasedNumberFormat.DURATION);
|
||||
}
|
||||
return gFormat;
|
||||
}
|
||||
|
||||
private static String diffTime(NumberFormat fmt, long start, long end) {
|
||||
if(fmt==null) {
|
||||
fmt = getFormat();
|
||||
}
|
||||
synchronized(fmt) {
|
||||
long age = end - start;
|
||||
long diff = age/1000; // millis per second. Workaround ticket:7936 by using whole number seconds.
|
||||
return fmt.format(diff);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -44,7 +44,6 @@
|
|||
<module>demos</module>
|
||||
<module>samples</module>
|
||||
<module>tools/misc</module>
|
||||
<module>tools/utilities-for-cldr</module>
|
||||
<module>perf-tests</module>
|
||||
</modules>
|
||||
|
||||
|
|
|
@ -1,277 +0,0 @@
|
|||
// © 2016 and later: Unicode, Inc. and others.
|
||||
// License & terms of use: http://www.unicode.org/copyright.html
|
||||
/*
|
||||
**********************************************************************
|
||||
* Copyright (c) 2002-2004, International Business Machines
|
||||
* Corporation and others. All Rights Reserved.
|
||||
**********************************************************************
|
||||
* Author: Alan Liu
|
||||
* Created: November 15 2002
|
||||
* Since: ICU 2.4
|
||||
**********************************************************************
|
||||
*/
|
||||
package com.ibm.icu.dev.tool.shared;
|
||||
|
||||
/**
|
||||
* A command-line option. A UOption specifies the name of an option
|
||||
* and whether or not it takes an argument. It is a mutable object
|
||||
* that later contains the option argument, if any, and a boolean
|
||||
* flag stating whether the option was seen or not.
|
||||
*
|
||||
* The static method parseArgs() takes an array of command-line
|
||||
* arguments and an array of UOptions and parses the command-line
|
||||
* arguments.
|
||||
*
|
||||
* This deliberately resembles the icu4c file uoption.[ch].
|
||||
*/
|
||||
public class UOption {
|
||||
|
||||
// Deliberated public data members
|
||||
public String longName;
|
||||
public String value;
|
||||
public Fn optionFn;
|
||||
public Object context;
|
||||
public char shortName;
|
||||
public int hasArg;
|
||||
public boolean doesOccur;
|
||||
|
||||
// Values of hasArg
|
||||
public static final int NO_ARG = 0;
|
||||
public static final int REQUIRES_ARG = 1;
|
||||
public static final int OPTIONAL_ARG = 2;
|
||||
|
||||
// Analog of UOptionFn. We don't pass in the context because the
|
||||
// functor can get it from the UOption.
|
||||
public interface Fn {
|
||||
int handle(UOption option);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UOption with the given attributes.
|
||||
*/
|
||||
public static UOption create(String aLongName,
|
||||
char aShortName,
|
||||
int hasArgument) {
|
||||
return new UOption(aLongName, aShortName, hasArgument);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a UOption with the given attributes.
|
||||
* Synonym for create(), for C compatibility.
|
||||
*/
|
||||
public static UOption DEF(String aLongName,
|
||||
char aShortName,
|
||||
int hasArgument) {
|
||||
return create(aLongName, aShortName, hasArgument);
|
||||
}
|
||||
|
||||
// Standard canned options. These create a new object when
|
||||
// called. Since the UOption object is mutable, we cannot use
|
||||
// static final instances.
|
||||
public static UOption HELP_H() { return create("help", 'h', NO_ARG); }
|
||||
public static UOption HELP_QUESTION_MARK() { return create("help", '?', NO_ARG); }
|
||||
public static UOption VERBOSE() { return create("verbose", 'v', NO_ARG); }
|
||||
public static UOption QUIET() { return create("quiet", 'q', NO_ARG); }
|
||||
public static UOption VERSION() { return create("version", 'V', NO_ARG); }
|
||||
public static UOption COPYRIGHT() { return create("copyright", 'c', NO_ARG); }
|
||||
|
||||
public static UOption DESTDIR() { return create("destdir", 'd', REQUIRES_ARG); }
|
||||
public static UOption SOURCEDIR() { return create("sourcedir", 's', REQUIRES_ARG); }
|
||||
public static UOption ENCODING() { return create("encoding", 'e', REQUIRES_ARG); }
|
||||
public static UOption ICUDATADIR() { return create("icudatadir", 'i', REQUIRES_ARG); }
|
||||
public static UOption PACKAGE_NAME() { return create("package-name", 'p', REQUIRES_ARG); }
|
||||
public static UOption BUNDLE_NAME() { return create("bundle-name", 'b', REQUIRES_ARG); }
|
||||
|
||||
/**
|
||||
* Java Command line argument parser.
|
||||
*
|
||||
* This function takes the argv[] command line and a description of
|
||||
* the program's options in form of an array of UOption structures.
|
||||
* Each UOption defines a long and a short name (a string and a character)
|
||||
* for options like "--foo" and "-f".
|
||||
*
|
||||
* Each option is marked with whether it does not take an argument,
|
||||
* requires one, or optionally takes one. The argument may follow in
|
||||
* the same argv[] entry for short options, or it may always follow
|
||||
* in the next argv[] entry.
|
||||
*
|
||||
* An argument is in the next argv[] entry for both long and short name
|
||||
* options, except it is taken from directly behind the short name in
|
||||
* its own argv[] entry if there are characters following the option letter.
|
||||
* An argument in its own argv[] entry must not begin with a '-'
|
||||
* unless it is only the '-' itself. There is no restriction of the
|
||||
* argument format if it is part of the short name options's argv[] entry.
|
||||
*
|
||||
* The argument is stored in the value field of the corresponding
|
||||
* UOption entry, and the doesOccur field is set to 1 if the option
|
||||
* is found at all.
|
||||
*
|
||||
* Short name options without arguments can be collapsed into a single
|
||||
* argv[] entry. After an option letter takes an argument, following
|
||||
* letters will be taken as its argument.
|
||||
*
|
||||
* If the same option is found several times, then the last
|
||||
* argument value will be stored in the value field.
|
||||
*
|
||||
* For each option, a function can be called. This could be used
|
||||
* for options that occur multiple times and all arguments are to
|
||||
* be collected.
|
||||
*
|
||||
* All options are removed from the argv[] array itself. If the parser
|
||||
* is successful, then it returns the number of remaining non-option
|
||||
* strings. (Unlike C, the Java argv[] array does NOT contain
|
||||
* the program name in argv[0].)
|
||||
*
|
||||
* An option "--" ends option processing; everything after this
|
||||
* remains in the argv[] array.
|
||||
*
|
||||
* An option string "-" alone is treated as a non-option.
|
||||
*
|
||||
* If an option is not recognized or an argument missing, then
|
||||
* the parser returns with the negative index of the argv[] entry
|
||||
* where the error was detected.
|
||||
*
|
||||
* @param argv this parameter is modified
|
||||
* @param start the first argument in argv[] to examine. Must be
|
||||
* 0..argv.length-1. Arguments from 0..start-1 are ignored.
|
||||
* @param options this parameter is modified
|
||||
* @return the number of unprocessed arguments in argv[], including
|
||||
* arguments 0..start-1.
|
||||
*/
|
||||
public static int parseArgs(String argv[], int start, UOption options[]) {
|
||||
String arg;
|
||||
int i=start, remaining=start;
|
||||
char c;
|
||||
boolean stopOptions=false;
|
||||
|
||||
while(i<argv.length) {
|
||||
arg=argv[i];
|
||||
if(!stopOptions && arg.length()>1 && arg.charAt(0)=='-') {
|
||||
/* process an option */
|
||||
c=arg.charAt(1);
|
||||
UOption option=null;
|
||||
arg=arg.substring(2);
|
||||
if(c=='-') {
|
||||
/* process a long option */
|
||||
if(arg.length()==0) {
|
||||
/* stop processing options after "--" */
|
||||
stopOptions=true;
|
||||
} else {
|
||||
/* search for the option string */
|
||||
int j;
|
||||
for(j=0; j<options.length; ++j) {
|
||||
if(options[j].longName != null && arg.equals(options[j].longName)) {
|
||||
option=options[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(option==null) {
|
||||
/* no option matches */
|
||||
syntaxError("Unknown option " + argv[i]);
|
||||
}
|
||||
option.doesOccur=true;
|
||||
|
||||
if(option.hasArg!=NO_ARG) {
|
||||
/* parse the argument for the option, if any */
|
||||
if(i+1<argv.length && !(argv[i+1].length()>1 && argv[i+1].charAt(0)=='-')) {
|
||||
/* argument in the next argv[], and there is not an option in there */
|
||||
option.value=argv[++i];
|
||||
} else if(option.hasArg==REQUIRES_ARG) {
|
||||
/* there is no argument, but one is required: return with error */
|
||||
syntaxError("Option " + argv[i] + " lacks required argument");
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* process one or more short options */
|
||||
for (;;) {
|
||||
/* search for the option letter */
|
||||
int j;
|
||||
for(j=0; j<options.length; ++j) {
|
||||
if(c==options[j].shortName) {
|
||||
option=options[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(option==null) {
|
||||
/* no option matches */
|
||||
syntaxError("Unknown option '" + c + "' in " + argv[i]);
|
||||
}
|
||||
option.doesOccur=true;
|
||||
|
||||
if(option.hasArg!=NO_ARG) {
|
||||
/* parse the argument for the option, if any */
|
||||
if(arg.length()!=0) {
|
||||
/* argument following in the same argv[] */
|
||||
option.value=arg;
|
||||
/* do not process the rest of this arg as option letters */
|
||||
break;
|
||||
} else if(i+1<argv.length && !(argv[i+1].length()>1 && argv[i+1].charAt(0)=='-')) {
|
||||
/* argument in the next argv[], and there is not an option in there */
|
||||
option.value=argv[++i];
|
||||
/* this break is redundant because we know that *arg==0 */
|
||||
break;
|
||||
} else if(option.hasArg==REQUIRES_ARG) {
|
||||
/* there is no argument, but one is required: return with error */
|
||||
syntaxError("Option -" + c + " lacks required argument");
|
||||
}
|
||||
}
|
||||
|
||||
/* get the next option letter */
|
||||
option=null;
|
||||
if (arg.length()==0) break;
|
||||
c=arg.charAt(0);
|
||||
arg=arg.substring(1);
|
||||
}
|
||||
}
|
||||
|
||||
if(option!=null && option.optionFn!=null && option.optionFn.handle(option)<0) {
|
||||
/* the option function was called and returned an error */
|
||||
syntaxError("Option handler failed for " + argv[i]);
|
||||
}
|
||||
|
||||
/* go to next argv[] */
|
||||
++i;
|
||||
} else {
|
||||
/* move a non-option up in argv[] */
|
||||
argv[remaining++]=arg;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return remaining;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the default to be set in an option list.
|
||||
* @param s
|
||||
* @return this
|
||||
*/public UOption setDefault(String s) {
|
||||
value = s;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenient method.
|
||||
*/
|
||||
public static int parseArgs(String argv[], UOption options[]) {
|
||||
return parseArgs(argv, 0, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private UOption(String aLongName,
|
||||
char aShortName,
|
||||
int hasArgument) {
|
||||
longName = aLongName;
|
||||
shortName = aShortName;
|
||||
hasArg = hasArgument;
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw an exception indicating a syntax error.
|
||||
*/
|
||||
private static void syntaxError(String message) {
|
||||
throw new IllegalArgumentException("Error in argument list: " + message);
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
* © 2023 and later: Unicode, Inc. and others.
|
||||
* License & terms of use: http://www.unicode.org/copyright.html
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j-root</artifactId>
|
||||
<version>76.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>utilities-for-cldr</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<proj.displayname>Utilities</proj.displayname>
|
||||
<mf.Automatic-Module-Name>com.ibm.icu.utilities</mf.Automatic-Module-Name>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-source</id>
|
||||
<phase>generate-sources</phase>
|
||||
<goals>
|
||||
<goal>add-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>../misc/src/main/java/com/ibm/icu/dev/tool/shared</source>
|
||||
<source>../../main/framework/src/test/java/com/ibm/icu/dev/util</source>
|
||||
<source>../../main/translit/src/test/java/com/ibm/icu/dev/util</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- Since this artifact is built from bits and pieces generating javadoc
|
||||
for it fails (can't access references). And we don't really need it.
|
||||
We publish the sources, and most IDEs can access the doc from there.
|
||||
-->
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<!-- We don't want this deployed to Maven Central. So by default we skip it. -->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.ibm.icu</groupId>
|
||||
<artifactId>icu4j</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>cldr_utilities</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<!-- Only deploy when the `cldr_utilities` profile is active,
|
||||
otherwise it will also be deployed to Maven Central.
|
||||
We only invoke this profile when we want to deploy to the GitHub Maven repository.
|
||||
We can even try to specify it here with `altDeploymentRepository`.
|
||||
-->
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>false</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
Loading…
Add table
Reference in a new issue