#line 23 "complete.def"
#line 34 "complete.def"
#include <config.h>
#include <stdio.h>
#include "../bashtypes.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "../bashansi.h"
#include "../bashintl.h"
#include "../shell.h"
#include "../builtins.h"
#include "../pcomplete.h"
#include "../bashline.h"
#include "common.h"
#include "bashgetopt.h"
#include <readline/readline.h>
#define STRDUP(x) ((x) ? savestring (x) : (char *)NULL)
static int find_compact __P((char *));
static int find_compopt __P((char *));
static int build_actions __P((WORD_LIST *, int *, int *, unsigned long *, unsigned long *));
static int remove_cmd_completions __P((WORD_LIST *));
static int print_one_completion __P((char *, COMPSPEC *));
static int print_compitem __P((BUCKET_CONTENTS *));
static void print_all_completions __P((void));
static int print_cmd_completions __P((WORD_LIST *));
static char *Garg, *Warg, *Parg, *Sarg, *Xarg, *Farg, *Carg;
static struct _compacts {
char *actname;
int actflag;
int actopt;
} compacts[] = {
{ "alias", CA_ALIAS, 'a' },
{ "arrayvar", CA_ARRAYVAR, 0 },
{ "binding", CA_BINDING, 0 },
{ "builtin", CA_BUILTIN, 'b' },
{ "command", CA_COMMAND, 'c' },
{ "directory", CA_DIRECTORY, 'd' },
{ "disabled", CA_DISABLED, 0 },
{ "enabled", CA_ENABLED, 0 },
{ "export", CA_EXPORT, 'e' },
{ "file", CA_FILE, 'f' },
{ "function", CA_FUNCTION, 0 },
{ "helptopic", CA_BUILTIN, 0 },
{ "hostname", CA_HOSTNAME, 0 },
{ "group", CA_GROUP, 'g' },
{ "job", CA_JOB, 'j' },
{ "keyword", CA_KEYWORD, 'k' },
{ "running", CA_RUNNING, 0 },
{ "service", CA_SERVICE, 's' },
{ "setopt", CA_SETOPT, 0 },
{ "shopt", CA_SHOPT, 0 },
{ "signal", CA_SIGNAL, 0 },
{ "stopped", CA_STOPPED, 0 },
{ "user", CA_USER, 'u' },
{ "variable", CA_VARIABLE, 'v' },
{ (char *)NULL, 0, 0 },
};
static struct _compopt {
char *optname;
int optflag;
} compopts[] = {
{ "bashdefault", COPT_BASHDEFAULT },
{ "default", COPT_DEFAULT },
{ "dirnames", COPT_DIRNAMES },
{ "filenames",COPT_FILENAMES},
{ "nospace", COPT_NOSPACE },
{ "plusdirs", COPT_PLUSDIRS },
{ (char *)NULL, 0 },
};
static int
find_compact (name)
char *name;
{
register int i;
for (i = 0; compacts[i].actname; i++)
if (STREQ (name, compacts[i].actname))
return i;
return -1;
}
static int
find_compopt (name)
char *name;
{
register int i;
for (i = 0; compopts[i].optname; i++)
if (STREQ (name, compopts[i].optname))
return i;
return -1;
}
static int
build_actions (list, pp, rp, actp, optp)
WORD_LIST *list;
int *pp, *rp;
unsigned long *actp, *optp;
{
int opt, ind, opt_given;
unsigned long acts, copts;
acts = copts = (unsigned long)0L;
opt_given = 0;
reset_internal_getopt ();
while ((opt = internal_getopt (list, "abcdefgjko:prsuvA:G:W:P:S:X:F:C:")) != -1)
{
opt_given = 1;
switch (opt)
{
case 'r':
if (rp)
{
*rp = 1;
break;
}
else
{
sh_invalidopt ("-r");
builtin_usage ();
return (EX_USAGE);
}
case 'p':
if (pp)
{
*pp = 1;
break;
}
else
{
sh_invalidopt ("-p");
builtin_usage ();
return (EX_USAGE);
}
case 'a':
acts |= CA_ALIAS;
break;
case 'b':
acts |= CA_BUILTIN;
break;
case 'c':
acts |= CA_COMMAND;
break;
case 'd':
acts |= CA_DIRECTORY;
break;
case 'e':
acts |= CA_EXPORT;
break;
case 'f':
acts |= CA_FILE;
break;
case 'g':
acts |= CA_GROUP;
break;
case 'j':
acts |= CA_JOB;
break;
case 'k':
acts |= CA_KEYWORD;
break;
case 's':
acts |= CA_SERVICE;
break;
case 'u':
acts |= CA_USER;
break;
case 'v':
acts |= CA_VARIABLE;
break;
case 'o':
ind = find_compopt (list_optarg);
if (ind < 0)
{
sh_invalidoptname (list_optarg);
return (EX_USAGE);
}
copts |= compopts[ind].optflag;
break;
case 'A':
ind = find_compact (list_optarg);
if (ind < 0)
{
builtin_error (_("%s: invalid action name"), list_optarg);
return (EX_USAGE);
}
acts |= compacts[ind].actflag;
break;
case 'C':
Carg = list_optarg;
break;
case 'F':
Farg = list_optarg;
break;
case 'G':
Garg = list_optarg;
break;
case 'P':
Parg = list_optarg;
break;
case 'S':
Sarg = list_optarg;
break;
case 'W':
Warg = list_optarg;
break;
case 'X':
Xarg = list_optarg;
break;
default:
builtin_usage ();
return (EX_USAGE);
}
}
*actp = acts;
*optp = copts;
return (opt_given ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}
int
complete_builtin (list)
WORD_LIST *list;
{
int opt_given, pflag, rflag, rval;
unsigned long acts, copts;
COMPSPEC *cs;
if (list == 0)
{
print_all_completions ();
return (EXECUTION_SUCCESS);
}
opt_given = pflag = rflag = 0;
acts = copts = (unsigned long)0L;
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
cs = (COMPSPEC *)NULL;
rval = build_actions (list, &pflag, &rflag, &acts, &copts);
if (rval == EX_USAGE)
return (rval);
opt_given = rval != EXECUTION_FAILURE;
list = loptend;
if (pflag || (list == 0 && opt_given == 0))
{
if (list == 0)
{
print_all_completions ();
return (EXECUTION_SUCCESS);
}
return (print_cmd_completions (list));
}
if (rflag)
{
if (list == 0)
{
progcomp_flush ();
return (EXECUTION_SUCCESS);
}
return (remove_cmd_completions (list));
}
if (list == 0 && opt_given)
{
builtin_usage ();
return (EX_USAGE);
}
cs = compspec_create ();
cs->actions = acts;
cs->options = copts;
cs->globpat = STRDUP (Garg);
cs->words = STRDUP (Warg);
cs->prefix = STRDUP (Parg);
cs->suffix = STRDUP (Sarg);
cs->funcname = STRDUP (Farg);
cs->command = STRDUP (Carg);
cs->filterpat = STRDUP (Xarg);
for (rval = EXECUTION_SUCCESS ; list; list = list->next)
{
if (progcomp_insert (list->word->word, cs) == 0)
rval = EXECUTION_FAILURE;
}
return (rval);
}
static int
remove_cmd_completions (list)
WORD_LIST *list;
{
WORD_LIST *l;
int ret;
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
if (progcomp_remove (l->word->word) == 0)
{
builtin_error (_("%s: no completion specification"), l->word->word);
ret = EXECUTION_FAILURE;
}
}
return ret;
}
#define SQPRINTARG(a, f) \
do { \
if (a) \
{ \
x = sh_single_quote (a); \
printf ("%s %s ", f, x); \
free (x); \
} \
} while (0)
#define PRINTARG(a, f) \
do { \
if (a) \
printf ("%s %s ", f, a); \
} while (0)
#define PRINTOPT(a, f) \
do { \
if (acts & a) \
printf ("%s ", f); \
} while (0)
#define PRINTACT(a, f) \
do { \
if (acts & a) \
printf ("-A %s ", f); \
} while (0)
#define PRINTCOMPOPT(a, f) \
do { \
if (copts & a) \
printf ("-o %s ", f); \
} while (0)
static int
print_one_completion (cmd, cs)
char *cmd;
COMPSPEC *cs;
{
unsigned long acts, copts;
char *x;
printf ("complete ");
copts = cs->options;
PRINTCOMPOPT (COPT_BASHDEFAULT, "bashdefault");
PRINTCOMPOPT (COPT_DEFAULT, "default");
PRINTCOMPOPT (COPT_DIRNAMES, "dirnames");
PRINTCOMPOPT (COPT_FILENAMES, "filenames");
PRINTCOMPOPT (COPT_NOSPACE, "nospace");
PRINTCOMPOPT (COPT_PLUSDIRS, "plusdirs");
acts = cs->actions;
PRINTOPT (CA_ALIAS, "-a");
PRINTOPT (CA_BUILTIN, "-b");
PRINTOPT (CA_COMMAND, "-c");
PRINTOPT (CA_DIRECTORY, "-d");
PRINTOPT (CA_EXPORT, "-e");
PRINTOPT (CA_FILE, "-f");
PRINTOPT (CA_GROUP, "-g");
PRINTOPT (CA_JOB, "-j");
PRINTOPT (CA_KEYWORD, "-k");
PRINTOPT (CA_SERVICE, "-s");
PRINTOPT (CA_USER, "-u");
PRINTOPT (CA_VARIABLE, "-v");
PRINTACT (CA_ARRAYVAR, "arrayvar");
PRINTACT (CA_BINDING, "binding");
PRINTACT (CA_DISABLED, "disabled");
PRINTACT (CA_ENABLED, "enabled");
PRINTACT (CA_FUNCTION, "function");
PRINTACT (CA_HELPTOPIC, "helptopic");
PRINTACT (CA_HOSTNAME, "hostname");
PRINTACT (CA_RUNNING, "running");
PRINTACT (CA_SETOPT, "setopt");
PRINTACT (CA_SHOPT, "shopt");
PRINTACT (CA_SIGNAL, "signal");
PRINTACT (CA_STOPPED, "stopped");
SQPRINTARG (cs->globpat, "-G");
SQPRINTARG (cs->words, "-W");
SQPRINTARG (cs->prefix, "-P");
SQPRINTARG (cs->suffix, "-S");
SQPRINTARG (cs->filterpat, "-X");
PRINTARG (cs->funcname, "-F");
PRINTARG (cs->command, "-C");
printf ("%s\n", cmd);
return (0);
}
static int
print_compitem (item)
BUCKET_CONTENTS *item;
{
COMPSPEC *cs;
char *cmd;
cmd = item->key;
cs = (COMPSPEC *)item->data;
return (print_one_completion (cmd, cs));
}
static void
print_all_completions ()
{
progcomp_walk (print_compitem);
}
static int
print_cmd_completions (list)
WORD_LIST *list;
{
WORD_LIST *l;
COMPSPEC *cs;
int ret;
for (ret = EXECUTION_SUCCESS, l = list; l; l = l->next)
{
cs = progcomp_search (l->word->word);
if (cs)
print_one_completion (l->word->word, cs);
else
{
builtin_error (_("%s: no completion specification"), l->word->word);
ret = EXECUTION_FAILURE;
}
}
return (ret);
}
#line 540 "complete.def"
int
compgen_builtin (list)
WORD_LIST *list;
{
int rval;
unsigned long acts, copts;
COMPSPEC *cs;
STRINGLIST *sl;
char *word, **matches;
if (list == 0)
return (EXECUTION_SUCCESS);
acts = copts = (unsigned long)0L;
Garg = Warg = Parg = Sarg = Xarg = Farg = Carg = (char *)NULL;
cs = (COMPSPEC *)NULL;
rval = build_actions (list, (int *)NULL, (int *)NULL, &acts, &copts);
if (rval == EX_USAGE)
return (rval);
if (rval == EXECUTION_FAILURE)
return (EXECUTION_SUCCESS);
list = loptend;
word = (list && list->word) ? list->word->word : "";
if (Farg)
builtin_error (_("warning: -F option may not work as you expect"));
if (Carg)
builtin_error (_("warning: -C option may not work as you expect"));
cs = compspec_create ();
cs->actions = acts;
cs->options = copts;
cs->refcount = 1;
cs->globpat = STRDUP (Garg);
cs->words = STRDUP (Warg);
cs->prefix = STRDUP (Parg);
cs->suffix = STRDUP (Sarg);
cs->funcname = STRDUP (Farg);
cs->command = STRDUP (Carg);
cs->filterpat = STRDUP (Xarg);
rval = EXECUTION_FAILURE;
sl = gen_compspec_completions (cs, "compgen", word, 0, 0);
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_BASHDEFAULT))
{
matches = bash_default_completion (word, 0, 0, 0, 0);
sl = completions_to_stringlist (matches);
strvec_dispose (matches);
}
if ((sl == 0 || sl->list_len == 0) && (copts & COPT_DEFAULT))
{
matches = rl_completion_matches (word, rl_filename_completion_function);
sl = completions_to_stringlist (matches);
strvec_dispose (matches);
}
if (sl)
{
if (sl->list && sl->list_len)
{
rval = EXECUTION_SUCCESS;
strlist_print (sl, (char *)NULL);
}
strlist_dispose (sl);
}
compspec_dispose (cs);
return (rval);
}