Name compression: {prefix}/{suffix} -> {prefix} if {prefix} is unique {prefix}/{suffix} -> {suffix} if {suffix} is unique {prefix}/{middle}/{suffix} -> {prefix}/{suffix} if unique Consider array subscripts independently from name portions. Apply name compression only to the most-preferred name for each node. Algorithm (greedy): Input is a name of the form: Name * shorten(startName) Name *startName; /* nk/.../n1/n0 */ { Name *best, *prefix, *suffix; int bestLength, length, i; best = startName; bestLength = nameLength(startName); /* Find small suffixes */ for (suffix = NULL, i = 0; i <= bestLength + 1; i++) { newName = "ni/.../n0"; if (totallyUnique(newName) && suffixUnique(newName)) { suffix = newName; break; } } if (suffix && nameLength(suffix) < bestLength) { best = suffix; bestLength = nameLength(suffix); } /* Find small prefixes */ for (prefix = NULL, i = bestLength + 1; i >= 0; i--) { newName = "nk/.../ni"; if (totallyUnique(newName) && prefixUnique(newName)) { prefix = newName; break; } } if (prefix && nameLength(prefix) < bestLength) { best = prefix; bestLength = nameLength(prefix); } /* * Consider eliding inner parts of the name. * This loop starts with the smallest length and goes up * to names of length bestLength. */ for (length = 1; length < bestLength; length++) if (genAllSubNames(startName, length, elideFunc, &best)) break; return best; } /* * totallyUnique -- * * Determine whether 'name' is unique with respect to all the * names currently in nameTable. * * Results: * TRUE if 'name' is unique, FALSE if not. * * Side effects: * None. */ bool totallyUnique(name) Name *name; { } /* * prefixUnique -- * * Compare 'name' with all other names in nameTable, looking * only at the leading components of these names. If 'name' * isn't unique with respect to the set of names formed by * the leading components, return FALSE. * * Results: * TRUE if 'name' is unique as described above, FALSE if not. * * Side effects: * None. */ bool prefixUnique(name) Name *name; { } /* * suffixUnique -- * * Compare 'name' with all other names in nameTable, looking * only at the trailing components of these names. If 'name' * isn't unique with respect to the set of names formed by * the trailing components, return FALSE. * * Results: * TRUE if 'name' is unique as described above, FALSE if not. * * Side effects: * None. */ bool suffixUnique(name) Name *name; { } /* * genAllSubNames -- * * Generate all subnames of 'name' that are of length 'subLength'. * Call (*func)() on each name, where (*func)() is of the following * form: * * int * (*func)(name, cdata) * Name *name; * ClientData cdata; * { * } * * This function should return 0 if genAllSubNames() should continue * generating names, or 1 if we should stop. * * Results: * Returns 1 if (*func)() aborted the generation; otherwise * returns 0. * * Side effects: * None other than those caused by (*func)(). */ int genAllSubNames(name, subLength, func, cdata) Name *name; int subLength; int (*func)(); ClientData cdata; { }