| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | /* pcomplib.c - library functions for programmable completion. */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  | /* Copyright (C) 1999-2009 Free Software Foundation, Inc.
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |    This file is part of GNU Bash, the Bourne Again SHell. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |    it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  |    the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |    (at your option) any later version. | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    Bash is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |    but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |    GNU General Public License for more details. | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-12 13:36:28 +00:00
										 |  |  |    You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |    along with Bash.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							|  |  |  | */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include <config.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (PROGRAMMABLE_COMPLETION)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "bashansi.h"
 | 
					
						
							|  |  |  | #include <stdio.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #if defined (HAVE_UNISTD_H)
 | 
					
						
							|  |  |  | #  ifdef _MINIX
 | 
					
						
							|  |  |  | #    include <sys/types.h>
 | 
					
						
							|  |  |  | #  endif
 | 
					
						
							|  |  |  | #  include <unistd.h>
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | #include "bashintl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | #include "shell.h"
 | 
					
						
							|  |  |  | #include "pcomplete.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  | #define COMPLETE_HASH_BUCKETS	256	/* must be power of two */
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #define STRDUP(x)	((x) ? savestring (x) : (char *)NULL)
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | HASH_TABLE *prog_completes = (HASH_TABLE *)NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  | static void free_progcomp __P((PTR_T)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | COMPSPEC * | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | compspec_create () | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   COMPSPEC *ret; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ret = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); | 
					
						
							|  |  |  |   ret->refcount = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   ret->actions = (unsigned long)0; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   ret->options = (unsigned long)0; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   ret->globpat = (char *)NULL; | 
					
						
							|  |  |  |   ret->words = (char *)NULL; | 
					
						
							|  |  |  |   ret->prefix = (char *)NULL; | 
					
						
							|  |  |  |   ret->suffix = (char *)NULL; | 
					
						
							|  |  |  |   ret->funcname = (char *)NULL; | 
					
						
							|  |  |  |   ret->command = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   ret->lcommand = (char *)NULL; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   ret->filterpat = (char *)NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | compspec_dispose (cs) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      COMPSPEC *cs; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   cs->refcount--; | 
					
						
							|  |  |  |   if (cs->refcount == 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |       FREE (cs->globpat); | 
					
						
							|  |  |  |       FREE (cs->words); | 
					
						
							|  |  |  |       FREE (cs->prefix); | 
					
						
							|  |  |  |       FREE (cs->suffix); | 
					
						
							|  |  |  |       FREE (cs->funcname); | 
					
						
							|  |  |  |       FREE (cs->command); | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |       FREE (cs->lcommand); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |       FREE (cs->filterpat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |       free (cs); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMPSPEC * | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | compspec_copy (cs) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      COMPSPEC *cs; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   COMPSPEC *new; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   new = (COMPSPEC *)xmalloc (sizeof (COMPSPEC)); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-09-15 16:59:08 -04:00
										 |  |  |   new->refcount = 1; 	/* was cs->refcount, but this is a fresh copy */ | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   new->actions = cs->actions; | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |   new->options = cs->options; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   new->globpat = STRDUP (cs->globpat); | 
					
						
							|  |  |  |   new->words = STRDUP (cs->words); | 
					
						
							|  |  |  |   new->prefix = STRDUP (cs->prefix); | 
					
						
							|  |  |  |   new->suffix = STRDUP (cs->suffix); | 
					
						
							|  |  |  |   new->funcname = STRDUP (cs->funcname); | 
					
						
							|  |  |  |   new->command = STRDUP (cs->command); | 
					
						
							| 
									
										
										
										
											2011-11-22 19:11:26 -05:00
										 |  |  |   new->lcommand = STRDUP (cs->lcommand); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   new->filterpat = STRDUP (cs->filterpat); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return new; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_create () | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   if (prog_completes == 0) | 
					
						
							|  |  |  |     prog_completes = hash_create (COMPLETE_HASH_BUCKETS); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_size () | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   return (HASH_ENTRIES (prog_completes)); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void | 
					
						
							|  |  |  | free_progcomp (data) | 
					
						
							| 
									
										
										
										
											2001-11-13 17:56:06 +00:00
										 |  |  |      PTR_T data; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   COMPSPEC *cs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cs = (COMPSPEC *)data; | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   compspec_dispose (cs); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  |    | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_flush () | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   if (prog_completes) | 
					
						
							|  |  |  |     hash_flush (prog_completes, free_progcomp); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							|  |  |  | progcomp_dispose () | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   if (prog_completes) | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |     hash_dispose (prog_completes); | 
					
						
							|  |  |  |   prog_completes = (HASH_TABLE *)NULL; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_remove (cmd) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |      char *cmd; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register BUCKET_CONTENTS *item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (prog_completes == 0) | 
					
						
							|  |  |  |     return 1; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   item = hash_remove (cmd, prog_completes, 0); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   if (item) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |       if (item->data) | 
					
						
							|  |  |  | 	free_progcomp (item->data); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |       free (item->key); | 
					
						
							|  |  |  |       free (item); | 
					
						
							|  |  |  |       return (1); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |   return (0); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | int | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_insert (cmd, cs) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |       char *cmd; | 
					
						
							|  |  |  |       COMPSPEC *cs; | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |   register BUCKET_CONTENTS *item; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (cs == NULL) | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |     programming_error (_("progcomp_insert: %s: NULL COMPSPEC"), cmd); | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (prog_completes == 0) | 
					
						
							|  |  |  |     progcomp_create (); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  |   cs->refcount++; | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   item = hash_insert (cmd, prog_completes, 0); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   if (item->data) | 
					
						
							|  |  |  |     free_progcomp (item->data); | 
					
						
							|  |  |  |   else | 
					
						
							|  |  |  |     item->key = savestring (cmd); | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   item->data = cs; | 
					
						
							| 
									
										
										
										
											2004-07-27 13:29:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |   return 1; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | COMPSPEC * | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_search (cmd) | 
					
						
							| 
									
										
										
										
											2001-04-06 19:14:31 +00:00
										 |  |  |      const char *cmd; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							|  |  |  |   register BUCKET_CONTENTS *item; | 
					
						
							|  |  |  |   COMPSPEC *cs; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   if (prog_completes == 0) | 
					
						
							|  |  |  |     return ((COMPSPEC *)NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   item = hash_search (cmd, prog_completes, 0); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |   if (item == NULL) | 
					
						
							|  |  |  |     return ((COMPSPEC *)NULL); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   cs = (COMPSPEC *)item->data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return (cs); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  | progcomp_walk (pfunc) | 
					
						
							|  |  |  |      hash_wfunc *pfunc; | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   if (prog_completes == 0 || pfunc == 0 || HASH_ENTRIES (prog_completes) == 0) | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  |     return; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-07-17 14:10:11 +00:00
										 |  |  |   hash_walk (prog_completes, pfunc); | 
					
						
							| 
									
										
										
										
											2000-03-17 21:46:59 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #endif /* PROGRAMMABLE_COMPLETION */
 |