+ /* Sort array by value. */
+ sort (items, n_items, sizeof *items, compare_arc_items, NULL);
+
+ /* Assign recoded values in sorted order. */
+ for (j = 0; j < n_items; j++)
+ {
+ const union value *from = &items[j]->from;
+ char *recoded_value = NULL;
+ const int src_width = items[j]->width;
+ union value to_val;
+ size_t len;
+
+ value_init (&to_val, 0);
+
+ items[j]->to = direction == ASCENDING ? j + 1 : n_items - j;
+
+ to_val.f = items[j]->to;
+
+ /* Add value labels to the destination variable which indicate
+ the source value from whence the new value comes. */
+ if (src_width > 0)
+ {
+ const char *str = CHAR_CAST_BUG (const char*, value_str (from, src_width));
+
+ recoded_value = recode_string (UTF8, dict_get_encoding (dict),
+ str, src_width);
+ }
+ else
+ recoded_value = c_xasprintf ("%g", from->f);
+
+ /* Remove trailing whitespace */
+ len = strlen (recoded_value);
+ while (len > 0 && recoded_value[len - 1] == ' ')
+ recoded_value[--len] = '\0';
+
+ var_add_value_label (spec->dst, &to_val, recoded_value);
+ value_destroy (&to_val, 0);
+ free (recoded_value);
+ }
+
+ /* Free array. */
+ free (items);