2011-08-31 81 views
0

我試圖讓命令完成的工作,但它似乎是其工作不正常.. 請看看我的代碼,並告訴我,我該如何解決呢..的ReadLine完成問題

在此先感謝。 ..

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) { // scan 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 

如果我用這樣一個char *test[7] = {"ls","cat","lso", "mk", "mkd", "mkdir",""};一切靜態數組似乎罰款,包括命令的執行..

+0

你是什麼意思由'不正常工作? –

+0

請看測試用例 – kanoz

+0

你在說什麼測試用例? –

回答

0

哪裏是命令[]和計算的定義/聲明?

另外:你的風格是不連貫的,程序幾乎不可讀。 爲什麼你在一個地方而不是在另一個地方施放malloc()的返回?

如果(x == 0){}和if(!x){}是等價的。做出選擇並堅持下去。

醜陋的做{...} while(...);循環可以替換爲for(...; ...; ...){}循環,爲您節省兩個縮進級別。

+0

這種醜陋的代碼實際上是將它寫入低級別C風格的效果,其中這些庫是編寫和需求的。例如,readline庫中的許多函數需要'char *'而不是'const char *',並且它們要求它由'malloc()'分配,因爲它們在使用後在內部使用'free()'解除分配。如果你給它們提供了一些未由'malloc()'分配的內容,它們將會出現段錯誤。令人毛骨悚然的libs =可怕的用戶代碼。 – SasQ