]> granicus.if.org Git - icu/commitdiff
ICU-20121 Adding span field for FormattedList.
authorShane F. Carr <shane@unicode.org>
Fri, 8 Feb 2019 10:07:00 +0000 (02:07 -0800)
committerShane F. Carr <shane@unicode.org>
Fri, 15 Feb 2019 00:05:51 +0000 (16:05 -0800)
icu4c/source/i18n/listformatter.cpp
icu4c/source/i18n/unicode/listformatter.h
icu4c/source/i18n/unicode/uformattedvalue.h
icu4c/source/i18n/unicode/ulistformatter.h
icu4c/source/test/cintltst/ulistfmttest.c
icu4c/source/test/intltest/listformattertest.cpp

index 5968284a79219b008f73dc4d86d1061e7aab48ec..68814211cdf70783cb7d08760192b0246c5c05d7 100644 (file)
@@ -420,6 +420,21 @@ FormattedList ListFormatter::formatStringsToValue(
     if (U_FAILURE(errorCode)) {
         return FormattedList(errorCode);
     }
+
+    // Add span fields and sort
+    ConstrainedFieldPosition cfpos;
+    cfpos.constrainField(UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD);
+    int32_t i = 0;
+    handler.setCategory(UFIELD_CATEGORY_LIST_SPAN);
+    while (result->nextPosition(cfpos, errorCode)) {
+        handler.addAttribute(i++, cfpos.getStart(), cfpos.getLimit());
+    }
+    handler.getError(errorCode);
+    if (U_FAILURE(errorCode)) {
+        return FormattedList(errorCode);
+    }
+    result->sort();
+
     return FormattedList(result.orphan());
 }
 #endif
index b11676d5f8052134c009503b1f013e711beec229..bf956ba52c57021ad541ad082dc224b7b6174354 100644 (file)
@@ -66,6 +66,13 @@ struct ListFormatData : public UMemory {
 /**
  * An immutable class containing the result of a list formatting operation.
  *
+ * When calling nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the nextPosition() iterator.
+ *
  * Not intended for public subclassing.
  *
  * @draft ICU 64
index 362408bfeb775a62ee4d73ab3b6976c5da7d1a8b..1fe977f30e9046d4c9c8515b915308fe79b73599 100644 (file)
@@ -79,6 +79,13 @@ typedef enum UFieldCategory {
     UFIELD_CATEGORY_COUNT,
 #endif
 
+    /**
+     * Category for spans in a list.
+     *
+     * @draft ICU 64
+     */
+    UFIELD_CATEGORY_LIST_SPAN = 0x1000 + UFIELD_CATEGORY_LIST,
+
     /**
      * Category for spans in a date interval.
      *
index cf730bfd7e30e04c6c909e283f5566e1294f359b..2afc50d847bd6467b5e426f516afd2816d7cfa4a 100644 (file)
@@ -114,6 +114,13 @@ ulistfmt_openResult(UErrorCode* ec);
  *
  * You can think of this method as a cast between types.
  *
+ * When calling ufmtval_nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the ufmtval_nextPosition() iterator.
+ *
  * @param uresult The object containing the formatted string.
  * @param ec Set if an error occurs.
  * @return A UFormattedValue owned by the input object.
index b89f1b37c77c690aefff2c892dae800f76c17c99..5eb5a1eaa4b700034c2094c44e8b9413e8423d03 100644 (file)
@@ -147,11 +147,14 @@ static void TestUListFmtToValue() {
         assertSuccess("Formatting", &ec);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
         checkMixedFormattedValue(
             message,
             ulistfmt_resultAsValue(fl, &ec),
@@ -175,19 +178,26 @@ static void TestUListFmtToValue() {
         assertSuccess("Formatting", &ec);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0,  1},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0,  1},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3,  4},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6,  7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9,  10},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 1,  3},
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 3,  4},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3,  4},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 4,  6},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 6,  7},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6,  7},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 7,  9},
+            {UFIELD_CATEGORY_LIST_SPAN, 3, 9,  10},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9,  10},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 10, 12},
+            {UFIELD_CATEGORY_LIST_SPAN, 4, 12, 13},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 13, 15},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 5, 15, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 6, 22, 23},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23}};
         checkMixedFormattedValue(
             message,
             ulistfmt_resultAsValue(fl, &ec),
index 239eb78ac09f8da3ace3be03c118d9ec0462b15a..955c3d981d44624dc2d201648a77de66b90388fc 100644 (file)
@@ -556,11 +556,14 @@ void ListFormatterTest::TestFormattedValue() {
         FormattedList result = fmt->formatStringsToValue(inputs, UPRV_LENGTHOF(inputs), status);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
         checkMixedFormattedValue(
             message,
             result,