char chr_legal[] = ;
int  chr_idx[256] = {0};
char idx_chr[256] = {0};


typedef struct trie_t *trie, trie_t;
struct trie_t {
    trie next[sizeof(chr_legal)]; 
    int eow;
};

trie trie_new() { return calloc(sizeof(trie_t), 1); }



trie trie_trav(trie root, const char * str, int no_create)
{
    int c;
    while (root) {
        if ((c = str[0]) == '\0') {
            if (!root->eow && no_create) return 0;
            break;
        }
        if (! (c = chr_idx[c]) ) {
            str++;
            continue;
        }

        if (!root->next[c]) {
            if (no_create) return 0;
            root->next[c] = trie_new();
        }
        root = root->next[c];
        str++;
    }
    return root;
}


int trie_all(trie root, char path[], int depth, int (*callback)(char *))
{
    int i;
    if (root->eow && !callback(path)) return 0;

    for (i = 1; i < sizeof(chr_legal); i++) {
        if (!root->next[i]) continue;

        path[depth] = idx_chr[i];
        path[depth + 1] = '\0';
        if (!trie_all(root->next[i], path, depth + 1, callback))
            return 0;
    }
    return 1;
}

void add_index(trie root, const char *word, const char *fname)
{
    trie x = trie_trav(root, word, 0);
    x->eow = 1;

    if (!x->next[FNAME])
        x->next[FNAME] = trie_new();
    x = trie_trav(x->next[FNAME], fname, 0);
    x->eow = 1;
}

int print_path(char *path)
{
    printf(, path);
    return 1;
}


const char *files[] = { , ,  };
const char *text[][5] ={{ , , , ,  },
                { , , , 0 },
                { , , , , 0 }};

trie init_tables()
{
    int i, j;
    trie root = trie_new();
    for (i = 0; i < sizeof(chr_legal); i++) {
        chr_idx[(int)chr_legal[i]] = i + 1;
        idx_chr[i + 1] = chr_legal[i];
    }




    void read_file(const char * fname) {
        char cmd[1024];
        char word[1024];
        sprintf(cmd, \\n\, fname);
        FILE *in = popen(cmd, );
        while (!feof(in)) {
            fscanf(in, , word);
            add_index(root, word, fname);
        }
        pclose(in);
    };

    read_file();
    read_file();
    read_file();

    for (i = 0; i < 3; i++) {
        for (j = 0; j < 5; j++) {
            if (!text[i][j]) break;
            add_index(root, text[i][j], files[i]);
        }
    }


    return root;
}

void search_index(trie root, const char *word)
{
    char path[1024];
    printf(%s\, word);
    trie found = find_word(root, word);

    if (!found) printf();
    else {
        trie_all(found->next[FNAME], path, 0, print_path);
        printf();
    }
}

int main()
{
    trie root = init_tables();

    search_index(root, );
    search_index(root, );
    search_index(root, );
    search_index(root, );
    return 0;
}