开发者

Readline Completion Problem

开发者 https://www.devze.com 2023-04-01 02:47 出处:网络
I am trying to get command completion working but it seems like its not working properly.. Please have a look at my code and tell me how I can fix it..

I am trying to get command completion working but it seems like its not working properly.. Please have a look at my code and tell me how I can fix it..

Thanks in advance...

char store_commands() {
        char *newEnv;
        DIR * dir;
        char *new ;          
        struct dirent * entry;
        char *env = getenv("PATH");

        do { 
                newEnv = strsep(&env, ":");

                if(newEnv != NULL) 
                        if(strlen(newEnv) > 0) {

                                dir = opendir(newEnv);
                                if( dir == NULL ) break;
                                if(flag == 1) {
                                        flag = 0;
                                        while((entry = readdir(dir)) != NULL) {
                                                new = malloc(strlen(entry->d_name) + 1) ;  
                                                new = strcpy(new, entry->d_name);

                                                commands[++count] = new;  // add possible commands into an array
                                                printf("---%i %s\n", count ,commands[count]);
                                        }
                                }
                                closedir(dir); // close directory
                        }
        } while(newEnv);

        return **commands;
}




static char** my_completion( const char * text , int start,  int end){
        char **matches;
        store_commands();

        matches = (char **)NULL;

        if (start == 0)
                matches = rl_completion_matches ((char*)text, &my_generator);


        return matches;

}

char * dupstr (char* s) {
        char *r;

        r = (char*) malloc ((strlen (s) + 1));
        strcpy (r, s);
        return (r);
}


char* my_generator(const char* text, int state) {
        int index, len;
        char *comm;
        if (!state) {
                index = 0;
                len = (int)strlen (text);
        }



        while ( (comm = commands[index])) {
                index++;

                if (strncmp (comm, text, len) == 0)
                        return (dupstr(comm));
        }


        return NULL;
}







int main (int argc,  char * argv[]) {

        char  *command;
        using_history();
        rl_readline_name = basename(argv[0]);
        rl_attempted_completion_function = my_completion;





        while ( (command = readline(" $ "))!= NULL ) {  // s开发者_如何学Gocan stdin  

                rl_bind_key('\t',rl_complete);

                if(strlen(command) > 0) 
                        add_history(command);


        }


        return 0;
}


Some test cases
l (tab)
Display all 1281 possibilities? (y or n) // all possibilities come up when I put one letter *** all possibilities wrong actually what I meant was all commands including the ones dont start with l

ls (tab)
ls        lsbom     lsdistcc  lsm       lso       lsvfs  // seems alright here

however if I press enter 

comm[0]: 'ls' and comm[1]: '(null)'  // execution of the command fails!!!  WHY????
Execution of the command is failed
: No such file or directory

If I use a static array like this one char *test[7] = {"ls","cat","lso", "mk", "mkd", "mkdir",""}; everything seems fine including execution of the command..


Where are the definitions/declarations for commands[] and count ?

Also: your style is incoherent, the program is barely readable. Why do you cast the return from malloc() at one place and not at another place?

If (x == 0) {} and if ( !x ) {} are equivalent. Make your choice and stick with it.

The ugly do { ... } while ( ... ); loop can be replaced by a for( ... ; ... ; ...) {} loop, saving you two levels of indentation.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号