mirror of
				https://github.com/troglobit/editline.git
				synced 2025-11-01 01:01:34 +08:00 
			
		
		
		
	Revert function pointers for rl_complete() and rl_list_possib() introduced in 0.2.2.
Instead merge afd8b4de9dca8ec6afc3 from http://github.com/heimdal/heimdal.git project. This lets rl_complete() and rl_list_possib() become wrapper functions calling a set of function pointers, set using rl_set_complete_func() and rl_set_list_possib_funct(). Each wrapper has a fallback to do filename completion, which in turn can be disabled by leaving out --enable-default-complete from the configure line. This change, admittedly quite intrusive for a library, is a better implementation in many ways. For one it is much more readable, but it also enables further adoption of other editline forks as well as a simpler implementation of GNU Readline function pointers rl_completion_entry_function and rl_attempted_completion_function at a later stage. My apologies to everyone for whom this change breaks backwards compatibility. For help on converting your code, please see examples/cli.c.
This commit is contained in:
		| @@ -84,8 +84,8 @@ int main(int ac __attribute__ ((unused)), char *av[] __attribute__ ((unused))) | |||||||
|    char	*prompt = "cli> "; |    char	*prompt = "cli> "; | ||||||
|  |  | ||||||
|    /* Setup callbacks */ |    /* Setup callbacks */ | ||||||
|    rl_complete = &my_rl_complete; |    rl_set_complete_func(&my_rl_complete); | ||||||
|    rl_list_possib = &my_rl_list_possib; |    rl_set_list_possib_func(&my_rl_list_possib); | ||||||
|  |  | ||||||
|    while ((line = readline(prompt)) != NULL) { |    while ((line = readline(prompt)) != NULL) { | ||||||
|       (void)printf("\t\t\t|%s|\n", line); |       (void)printf("\t\t\t|%s|\n", line); | ||||||
|   | |||||||
| @@ -21,12 +21,18 @@ | |||||||
| #ifndef __EDITLINE_H__ | #ifndef __EDITLINE_H__ | ||||||
| #define __EDITLINE_H__ | #define __EDITLINE_H__ | ||||||
|  |  | ||||||
|  | /* Editline specific types, despite rl_ prefix.  From Heimdal project. */ | ||||||
|  | typedef char* (*rl_complete_func_t)(char*, int*); | ||||||
|  | typedef int (*rl_list_possib_func_t)(char*, char***); | ||||||
|  |  | ||||||
| /* Display print 8-bit chars as `M-x' or as the actual 8-bit char?  (Default:1) */ | /* Display print 8-bit chars as `M-x' or as the actual 8-bit char?  (Default:1) */ | ||||||
| extern int rl_meta_chars; | extern int rl_meta_chars; | ||||||
|  |  | ||||||
| /* Assign these to get command completion, see cli.c for example usage. */ | /* Use these functions to set custom command/file completion, see cli.c for example usage. */ | ||||||
| extern char *(*rl_complete)   (char *token, int *match); | rl_complete_func_t    rl_set_complete_func(rl_complete_func_t func); | ||||||
| extern int   (*rl_list_possib)(char *token, char ***av); | rl_list_possib_func_t rl_set_list_possib_func(rl_list_possib_func_t func); | ||||||
|  |  | ||||||
|  | /* Editline specific functions. */ | ||||||
|  |  | ||||||
| /* For compatibility with FSF readline. */ | /* For compatibility with FSF readline. */ | ||||||
| extern int         rl_point; | extern int         rl_point; | ||||||
|   | |||||||
| @@ -156,9 +156,19 @@ static int SplitPath(char *path, char **dirpart, char **filepart) | |||||||
|     return 0; |     return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static rl_complete_func_t el_complete_func = NULL; | ||||||
|  |  | ||||||
|  | /* For compatibility with the Heimdal project. */ | ||||||
|  | rl_complete_func_t rl_set_complete_func(rl_complete_func_t func) | ||||||
|  | { | ||||||
|  |     rl_complete_func_t old = el_complete_func; | ||||||
|  |     el_complete_func = func; | ||||||
|  |     return old; | ||||||
|  | } | ||||||
|  |  | ||||||
| /* Attempt to complete the pathname, returning an allocated copy. | /* Attempt to complete the pathname, returning an allocated copy. | ||||||
|  * Fill in *unique if we completed it, or set it to 0 if ambiguous. */ |  * Fill in *match if we completed it, or set it to 0 if ambiguous. */ | ||||||
| char *default_rl_complete(char *pathname, int *unique) | char *el_filename_complete(char *pathname, int *match) | ||||||
| { | { | ||||||
|     char        **av; |     char        **av; | ||||||
|     char        *dir; |     char        *dir; | ||||||
| @@ -185,7 +195,7 @@ char *default_rl_complete(char *pathname, int *unique) | |||||||
|     len = strlen(file); |     len = strlen(file); | ||||||
|     if (ac == 1) { |     if (ac == 1) { | ||||||
|         /* Exactly one match -- finish it off. */ |         /* Exactly one match -- finish it off. */ | ||||||
|         *unique = 1; |         *match = 1; | ||||||
|         j = strlen(av[0]) - len + 2; |         j = strlen(av[0]) - len + 2; | ||||||
| 	p = malloc(sizeof(char) * (j + 1)); | 	p = malloc(sizeof(char) * (j + 1)); | ||||||
|         if (p) { |         if (p) { | ||||||
| @@ -200,7 +210,7 @@ char *default_rl_complete(char *pathname, int *unique) | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     else { |     else { | ||||||
|         *unique = 0; |         *match = 0; | ||||||
|         if (len) { |         if (len) { | ||||||
|             /* Find largest matching substring. */ |             /* Find largest matching substring. */ | ||||||
|             for (i = len, end = strlen(av[0]); i < end; i++) |             for (i = len, end = strlen(av[0]); i < end; i++) | ||||||
| @@ -229,8 +239,30 @@ char *default_rl_complete(char *pathname, int *unique) | |||||||
|     return p; |     return p; | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Return all possible completions. */ | char *rl_complete(char *token, int *match) | ||||||
| int default_rl_list_possib(char *pathname, char ***avp) | { | ||||||
|  |     if (el_complete_func) | ||||||
|  | 	return el_complete_func(token, match); | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_DEFAULT_COMPLETE | ||||||
|  |     return el_filename_complete(token, match); | ||||||
|  | #else | ||||||
|  |     return NULL; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static rl_list_possib_func_t el_list_possib_func = NULL; | ||||||
|  |  | ||||||
|  | /* For compatibility with the Heimdal project. */ | ||||||
|  | rl_list_possib_func_t rl_set_list_possib_func(rl_list_possib_func_t func) | ||||||
|  | { | ||||||
|  |     rl_list_possib_func_t old = el_list_possib_func; | ||||||
|  |     el_list_possib_func = func; | ||||||
|  |     return old; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Default possible completions. */ | ||||||
|  | int el_filename_list_possib(char *pathname, char ***av) | ||||||
| { | { | ||||||
|     char        *dir; |     char        *dir; | ||||||
|     char        *file; |     char        *file; | ||||||
| @@ -239,13 +271,27 @@ int default_rl_list_possib(char *pathname, char ***avp) | |||||||
|     if (SplitPath(pathname, &dir, &file) < 0) |     if (SplitPath(pathname, &dir, &file) < 0) | ||||||
|         return 0; |         return 0; | ||||||
|  |  | ||||||
|     ac = FindMatches(dir, file, avp); |     ac = FindMatches(dir, file, av); | ||||||
|     free(dir); |     free(dir); | ||||||
|     free(file); |     free(file); | ||||||
|  |  | ||||||
|     return ac; |     return ac; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | /* Return all possible completions. */ | ||||||
|  | int rl_list_possib(char *token, char ***av) | ||||||
|  | { | ||||||
|  |     if (el_list_possib_func) | ||||||
|  | 	return el_list_possib_func(token, av); | ||||||
|  |  | ||||||
|  | #ifdef CONFIG_DEFAULT_COMPLETE | ||||||
|  |     return el_filename_list_possib(token, av); | ||||||
|  | #else | ||||||
|  |     return 0; | ||||||
|  | #endif | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Local Variables: |  * Local Variables: | ||||||
|  *  version-control: t |  *  version-control: t | ||||||
|   | |||||||
| @@ -115,8 +115,6 @@ const char       *rl_readline_name;/* Set by calling program, for conditional pa | |||||||
|  |  | ||||||
| /* User definable callbacks. */ | /* User definable callbacks. */ | ||||||
| char **(*rl_attempted_completion_function)(const char *token, int start, int end); | char **(*rl_attempted_completion_function)(const char *token, int start, int end); | ||||||
| char  *(*rl_comlete)(char *token, int *match); |  | ||||||
| int    (*rl_list_possib)(char *token, char ***av); |  | ||||||
|  |  | ||||||
| /* Declarations. */ | /* Declarations. */ | ||||||
| static char     *editinput(void); | static char     *editinput(void); | ||||||
| @@ -1018,20 +1016,6 @@ void rl_reset_terminal(char *p __attribute__((__unused__))) | |||||||
|  |  | ||||||
| void rl_initialize(void) | void rl_initialize(void) | ||||||
| { | { | ||||||
| #ifdef CONFIG_DEFAULT_COMPLETE |  | ||||||
|     int done = 0; |  | ||||||
|  |  | ||||||
|     if (!done) |  | ||||||
|     { |  | ||||||
|         if (!rl_complete) |  | ||||||
|             rl_complete = &default_rl_complete; |  | ||||||
|  |  | ||||||
|         if (!rl_list_possib) |  | ||||||
|             rl_list_possib = &default_rl_list_possib; |  | ||||||
|  |  | ||||||
|         done = 1; |  | ||||||
|     } |  | ||||||
| #endif |  | ||||||
| } | } | ||||||
|  |  | ||||||
| char *readline(const char *prompt) | char *readline(const char *prompt) | ||||||
| @@ -1155,10 +1139,6 @@ static el_status_t c_possible(void) | |||||||
|     char        *word; |     char        *word; | ||||||
|     int         ac; |     int         ac; | ||||||
|  |  | ||||||
|     if (!rl_list_possib) { |  | ||||||
|         return ring_bell(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     word = find_word(); |     word = find_word(); | ||||||
|     ac = rl_list_possib((char *)word, (char ***)&av); |     ac = rl_list_possib((char *)word, (char ***)&av); | ||||||
|     if (word) |     if (word) | ||||||
| @@ -1171,6 +1151,7 @@ static el_status_t c_possible(void) | |||||||
|  |  | ||||||
|         return CSmove; |         return CSmove; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return ring_bell(); |     return ring_bell(); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -1182,10 +1163,6 @@ static el_status_t c_complete(void) | |||||||
|     int         unique; |     int         unique; | ||||||
|     el_status_t s = 0; |     el_status_t s = 0; | ||||||
|  |  | ||||||
|     if (!rl_complete) { |  | ||||||
|         return ring_bell(); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     word = find_word(); |     word = find_word(); | ||||||
|     p = (char *)rl_complete((char *)word, &unique); |     p = (char *)rl_complete((char *)word, &unique); | ||||||
|     if (word) |     if (word) | ||||||
|   | |||||||
| @@ -73,12 +73,10 @@ extern int	rl_quit; | |||||||
| #ifdef CONFIG_SIGSTOP | #ifdef CONFIG_SIGSTOP | ||||||
| extern int	rl_susp; | extern int	rl_susp; | ||||||
| #endif | #endif | ||||||
| #ifdef CONFIG_DEFAULT_COMPLETE | void  rl_ttyset(int Reset); | ||||||
| extern char	*default_rl_complete(char *pathname, int *unique); | void  rl_add_slash(char *path, char *p); | ||||||
| extern int	default_rl_list_possib(char *pathname, char ***avp); | char *rl_complete(char *token, int *match); | ||||||
| #endif | int   rl_list_possib(char *token, char ***av); | ||||||
| extern void     rl_ttyset(int Reset); |  | ||||||
| extern void	rl_add_slash(char *path, char *p); |  | ||||||
|  |  | ||||||
| #ifndef HAVE_STDLIB_H | #ifndef HAVE_STDLIB_H | ||||||
| extern char	*getenv(const char *name); | extern char	*getenv(const char *name); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Joachim Nilsson
					Joachim Nilsson