+ /*
+ * compute the maximum size of the string-table.
+ */
+ str_size = strlen(to->term_names) + 1;
+ for_each_string(i, from) {
+ if (VALID_STRING(from->Strings[i]))
+ str_size += strlen(from->Strings[i]) + 1;
+ }
+ for_each_string(i, to) {
+ if (VALID_STRING(to->Strings[i]))
+ str_size += strlen(to->Strings[i]) + 1;
+ }
+ /* allocate a string-table large enough for both source/target, and
+ * copy all of the strings into that table. In the merge, we will
+ * select from the original source/target lists to construct a new
+ * target list.
+ */
+ if (str_size != 0) {
+ char *str_copied;
+ if ((str_table = malloc(str_size)) == NULL)
+ _nc_err_abort(MSG_NO_MEMORY);
+ str_copied = str_table;
+ _nc_STRCPY(str_copied, to->term_names, str_size);
+ to->term_names = str_copied;
+ copy_size = strlen(str_copied) + 1;
+ str_copied += copy_size;
+ str_size -= copy_size;
+ for_each_string(i, from) {
+ if (VALID_STRING(from->Strings[i])) {
+ _nc_STRCPY(str_copied, from->Strings[i], str_size);
+ from->Strings[i] = str_copied;
+ copy_size = strlen(str_copied) + 1;
+ str_copied += copy_size;
+ str_size -= copy_size;
+ }
+ }
+ for_each_string(i, to) {
+ if (VALID_STRING(to->Strings[i])) {
+ _nc_STRCPY(str_copied, to->Strings[i], str_size);
+ to->Strings[i] = str_copied;
+ copy_size = strlen(str_copied) + 1;
+ str_copied += copy_size;
+ str_size -= copy_size;
+ }
+ }
+ free(to->str_table);
+ to->str_table = str_table;
+ free(from->str_table);
+ }
+ /*
+ * Do the same for the extended-strings (i.e., lists of capabilities).
+ */
+ str_size = 0;
+ for (i = 0; i < NUM_EXT_NAMES(from); ++i) {
+ if (VALID_STRING(from->ext_Names[i]))
+ str_size += strlen(from->ext_Names[i]) + 1;
+ }
+ for (i = 0; i < NUM_EXT_NAMES(to); ++i) {
+ if (VALID_STRING(to->ext_Names[i]))
+ str_size += strlen(to->ext_Names[i]) + 1;
+ }
+ /* allocate a string-table large enough for both source/target, and
+ * copy all of the strings into that table. In the merge, we will
+ * select from the original source/target lists to construct a new
+ * target list.
+ */
+ if (str_size != 0) {
+ char *str_copied;
+ if ((str_table = malloc(str_size)) == NULL)
+ _nc_err_abort(MSG_NO_MEMORY);
+ str_copied = str_table;
+ for (i = 0; i < NUM_EXT_NAMES(from); ++i) {
+ if (VALID_STRING(from->ext_Names[i])) {
+ _nc_STRCPY(str_copied, from->ext_Names[i], str_size);
+ from->ext_Names[i] = str_copied;
+ copy_size = strlen(str_copied) + 1;
+ str_copied += copy_size;
+ str_size -= copy_size;
+ }
+ }
+ for (i = 0; i < NUM_EXT_NAMES(to); ++i) {
+ if (VALID_STRING(to->ext_Names[i])) {
+ _nc_STRCPY(str_copied, to->ext_Names[i], str_size);
+ to->ext_Names[i] = str_copied;
+ copy_size = strlen(str_copied) + 1;
+ str_copied += copy_size;
+ str_size -= copy_size;
+ }
+ }
+ free(to->ext_str_table);
+ to->ext_str_table = str_table;
+ free(from->ext_str_table);
+ }