+extern char *skip_compress;
+
+static int compression_level, per_file_default_level;
+
+struct suffix_tree {
+ struct suffix_tree *sibling;
+ struct suffix_tree *child;
+ char letter, word_end;
+};
+
+static char *match_list;
+static struct suffix_tree *suftree;
+
+static void add_suffix(struct suffix_tree **prior, char ltr, const char *str)
+{
+ struct suffix_tree *node, *newnode;
+
+ if (ltr == '[') {
+ const char *after = strchr(str, ']');
+ /* Treat "[foo" and "[]" as having a literal '['. */
+ if (after && after++ != str+1) {
+ while ((ltr = *str++) != ']')
+ add_suffix(prior, ltr, after);
+ return;
+ }
+ }
+
+ for (node = *prior; node; prior = &node->sibling, node = node->sibling) {
+ if (node->letter == ltr) {
+ if (*str)
+ add_suffix(&node->child, *str, str+1);
+ else
+ node->word_end = 1;
+ return;
+ }
+ if (node->letter > ltr)
+ break;
+ }
+ if (!(newnode = new(struct suffix_tree)))
+ out_of_memory("add_suffix");
+ newnode->sibling = node;
+ newnode->child = NULL;
+ newnode->letter = ltr;
+ *prior = newnode;
+ if (*str) {
+ add_suffix(&newnode->child, *str, str+1);
+ newnode->word_end = 0;
+ } else
+ newnode->word_end = 1;
+}
+
+static void add_nocompress_suffixes(const char *str)
+{
+ char *buf, *t;
+ const char *f = str;
+
+ if (!(buf = new_array(char, strlen(f) + 1)))
+ out_of_memory("add_nocompress_suffixes");