Jspice3
complete.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Wayne A. Christopher
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * Command completion code. We keep a data structure with information on each
10  * command, to make lookups fast. We also keep NCLASSES (which is sort of
11  * hardwired as 32) sets of keywords. Each command has an array of NARGS
12  * bitmasks (also hardwired as 4), stating whether the command takes that
13  * particular class of keywords in that position. Class 0 always means
14  * filename completion.
15  */
16 
17 #include "spice.h"
18 #include "cpdefs.h"
19 
20 #include <sys/types.h>
21 #ifdef HAVE_DIRENT_H
22 #include <dirent.h>
23 #ifndef direct
24 #define direct dirent
25 #endif
26 #else
27 #ifdef HAVE_SYS_DIR_H
28 #include <sys/dir.h>
29 #endif
30 #endif
31 #ifdef HAVE_GETPWUID
32 #include <pwd.h>
33 #endif
34 
35 /* Be sure the ioctls get included in the following */
36 #ifdef HAVE_TERMIOS_H
37 #include <termios.h>
38 #else
39 #ifdef HAVE_TERMIO_H
40 #include <termio.h>
41 #else
42 #ifdef HAVE_SGTTY_H
43 #include <sgtty.h>
44 #endif
45 #endif
46 #endif
47 
48 #include "suffix.h"
49 
50 #define CNTRL_D '\004'
51 #define ESCAPE '\033'
52 #define NCLASSES 32
53 #define NARGS 4
54 
55 #ifdef __STDC__
56 static struct ccom *getccom(char*);
57 static wordlist *ccfilec(char*);
58 static wordlist *ccmatch(char*,struct ccom**);
59 static void printem(wordlist*);
60 static wordlist *cctowl(struct ccom*,bool);
61 static void throwaway(struct ccom*);
62 static struct ccom *clookup(char*,struct ccom**,bool,bool);
63 static void cdelete(struct ccom*);
64 #else
65 static struct ccom *getccom();
66 static wordlist *ccfilec();
67 static wordlist *ccmatch();
68 static void printem();
69 static wordlist *cctowl();
70 static void throwaway();
71 static struct ccom *clookup();
72 static void cdelete();
73 #endif
74 
75 bool cp_nocc; /* Don't do command completion. */
76 
77 /* The data structure for the commands is as follows: every node has a pointer
78  * to its leftmost child, where the children of a node are those of which
79  * the node is a prefix. This means that for a word like "ducks", there
80  * must be nodes "d", "du", "duc", etc (which are all marked "invalid",
81  * of course). This data structure is called a "trie".
82  */
83 
84 struct ccom {
85  char *cc_name; /* Command or keyword name. */
86  long cc_kwords[NARGS]; /* What this command takes. */
87  char cc_invalid; /* This node has been deleted. */
88  struct ccom *cc_child; /* Left-most child. */
89  struct ccom *cc_sibling; /* Right (alph. greater) sibling. */
90  struct ccom *cc_ysibling; /* Left (alph. less) sibling. */
91  struct ccom *cc_parent; /* Parent node. */
92 } ;
93 
94 static struct ccom *commands = NULL; /* The available commands. */
95 static struct ccom *keywords[NCLASSES]; /* Keywords. */
96 
97 #ifdef TIOCSTI
98 
99 
100 void
101 cp_ccom(wlist, buf, esc)
102 
103 wordlist *wlist;
104 char *buf;
105 bool esc;
106 {
107  struct ccom *cc;
108  wordlist *a, *pmatches = NULL;
109  char wbuf[BSIZE_SP], *s, xbuf[BSIZE_SP];
110  int i, j, arg;
111 
112  strcpy(xbuf,buf);
113  cp_unquote(xbuf);
114  cp_wstrip(xbuf);
115  if (wlist->wl_next) { /* Not the first word. */
116  cc = getccom(wlist->wl_word);
117  if (cc && cc->cc_invalid)
118  cc = NULL;
119  arg = wl_length(wlist) - 2;
120  if (arg > 3)
121  arg = 3;
122  /* First filenames. */
123  if (cc && (cc->cc_kwords[arg] & 1)) {
124  pmatches = ccfilec(xbuf);
125  s = strrchr(xbuf, DIR_TERM);
126  i = strlen(s ? s + 1 : xbuf);
127  if ((*xbuf == '~') && !strchr(xbuf, DIR_TERM))
128  i--;
129  }
130 
131  /* The keywords. */
132  for (j = 1; j < NCLASSES; j++) {
133  if (cc && (cc->cc_kwords[arg] & (1 << j))) {
134  /* Find all the matching keywords. */
135  a = ccmatch(xbuf, &keywords[j]);
136  i = strlen(xbuf);
137  if (pmatches)
138  pmatches = wl_append(pmatches, a);
139  else
140  pmatches = a;
141  }
142  }
143  wl_sort(pmatches);
144  }
145  else {
146  pmatches = ccmatch(xbuf, &commands);
147  i = strlen(xbuf);
148  }
149  if (!esc) {
150  printem(pmatches);
151  wl_free(pmatches);
152  return;
153  }
154 
155  if (pmatches == NULL) {
156  (void) putchar('\07');
157  (void) fflush(cp_out);
158  return;
159  }
160  if (pmatches->wl_next == NULL) {
161  (void) strcpy(wbuf, &pmatches->wl_word[i]);
162  goto found;
163  }
164  /* Now we know which words might work. Extend the command as much
165  * as possible, then TIOCSTI the characters out.
166  */
167  for (j = 0;; j++, i++) {
168  wbuf[j] = pmatches->wl_word[i];
169  for (a = pmatches->wl_next; a; a = a->wl_next)
170  if (a->wl_word[i] != wbuf[j]) {
171  (void) fflush(cp_out);
172  wbuf[j] = '\0';
173  goto found;
174  }
175  if (wbuf[j] == '\0')
176  goto found;
177  }
178 found:
179  for (i = 0; wbuf[i]; i++)
180  (void) ioctl(fileno(cp_in), TIOCSTI, &wbuf[i]);
181  wl_free(pmatches);
182  return;
183 }
184 
185 
186 /* Figure out what the command is, given the name. Returns NULL if there
187  * is no such command in the command list. This is tricky, because we have
188  * to do a preliminary history and alias parse. (Or at least we should.)
189  */
190 
191 static struct ccom *
192 getccom(first)
193 
194 char *first;
195 {
196  struct alias *al;
197  int ntries = 21;
198 
199  /* First look for aliases. Just interested in the first word...
200  * Don't bother doing history yet -- that might get complicated.
201  */
202  while (ntries-- > 0) {
203  for (al = cp_aliases; al; al = al->al_next)
204  if (eq(first, al->al_name)) {
205  first = al->al_text->wl_word;
206  break;
207  }
208  if (al == NULL)
209  break;
210  }
211  if (ntries == 0) {
212  fprintf(cp_err, "\nError: alias loop.\n");
213  return (NULL);
214  }
215  return (clookup(first, &commands, false, false));
216 }
217 
218 
219 /* Figure out what files match the prefix. */
220 
221 static wordlist *
222 ccfilec(buf)
223 
224 char *buf;
225 {
226  DIR *wdir;
227  char *lcomp, *dir;
228  struct direct *de;
229  wordlist *wl = NULL, *t;
230 #ifdef HAVE_GETPWUID
231  struct passwd *pw;
232 #endif
233 
234  lcomp = strrchr(buf, DIR_TERM);
235  if (lcomp == NULL) {
236  lcomp = buf;
237 #ifdef HAVE_GETPWUID
238  if (*buf == cp_til) { /* User name completion... */
239  buf++;
240  while (pw = getpwent()) {
241  if (prefix(buf, pw->pw_name)) {
242  if (wl == NULL)
243  wl = alloc(struct wordlist);
244  else {
245  t = wl;
246  wl = alloc(struct wordlist);
247  wl->wl_next = t;
248  }
249  wl->wl_word = copy(pw->pw_name);
250  }
251  }
252  (void) endpwent();
253  return (wl);
254  }
255 #endif
256  wdir = opendir(".");
257  }
258  else {
259  *lcomp = '\0';
260  dir = cp_tildexpand(buf);
261  *lcomp = DIR_TERM;
262  lcomp++;
263  if (dir == NULL)
264  return (NULL);
265  wdir = opendir(dir);
266  txfree(dir);
267  }
268  if (wdir == NULL) {
269  return (NULL);
270  }
271  while (de = readdir(wdir))
272  if ((prefix(lcomp, de->d_name)) && (*lcomp ||
273  (*de->d_name != '.'))) {
274  if (wl == NULL)
275  wl = alloc(struct wordlist);
276  else {
277  t = wl;
278  wl = alloc(struct wordlist);
279  wl->wl_next = t;
280  }
281  wl->wl_word = copy(de->d_name);
282  }
283  (void) closedir(wdir);
284  wl_sort(wl);
285  return (wl);
286 }
287 
288 
289 /* See what keywords or commands match the prefix. Check extra also for
290  * matches, if it is non-NULL. Return a wordlist which is in alphabetical
291  * order. Note that we have to call this once for each class.
292  */
293 
294 static wordlist *
295 ccmatch(word, dbase)
296 
297 char *word;
298 struct ccom **dbase;
299 {
300  wordlist *wl;
301  register struct ccom *cc;
302 
303  cc = clookup(word, dbase, true, false);
304  if (cc) {
305  if (*word) /* This is a big drag. */
306  wl = cctowl(cc, false);
307  else
308  wl = cctowl(cc, true);
309  }
310  else
311  wl = NULL;
312  return (wl);
313 }
314 
315 
316 /* Print the words in the wordlist in columns. They are already sorted...
317  * This is a hard thing to do with wordlists...
318  */
319 
320 static void
321 printem(wl)
322 
323 wordlist *wl;
324 {
325  wordlist *ww;
326  int maxl = 0, num, i, j, k, width, ncols, nlines;
327  int shrink = 0;
328 
329  if (wl == NULL)
330  return;
331  out_winsize(&width,NULL);
332  out_init();
333  out_send("\n\n");
334  num = wl_length(wl);
335  for (ww = wl; ww; ww = ww->wl_next) {
336  j = strlen(ww->wl_word);
337  if (j > maxl)
338  maxl = j;
339  }
340  if (++maxl % 8)
341  maxl += 8 - (maxl % 8);
342  ncols = width / maxl;
343  if (width == maxl * ncols) shrink = 1;
344  if (ncols == 0)
345  ncols = 1;
346  nlines = num / ncols + (num % ncols ? 1 : 0);
347  for (k = 0; k < nlines; k++) {
348  for (i = 0; i < ncols; i++) {
349  j = i*nlines + k;
350  if (j < num) {
351  out_printf("%-*s",maxl-shrink*(i+1)/ncols,
352  wl_nthelem(j, wl)->wl_word);
353  }
354  else
355  break;
356  }
357  out_send("\n");
358  }
359  out_send("\n");
360  return;
361 }
362 
363 #else /* if not TIOCSTI */
364 void
365 cp_ccom(wlist, buf, esc)
366 
367 wordlist *wlist;
368 char *buf;
369 bool esc;
370 {
371  return;
372 }
373 #endif
374 
375 static wordlist *
376 cctowl(cc, sib)
377 
378 struct ccom *cc;
379 bool sib;
380 {
381  wordlist *wl, *end;
382 
383  if (!cc)
384  return (NULL);
385  if (!cc->cc_invalid) {
386  wl = alloc(struct wordlist);
387  wl->wl_word = copy(cc->cc_name);
388  wl->wl_next = cctowl(cc->cc_child, true);
389  if (wl->wl_next)
390  wl->wl_next->wl_prev = wl;
391  }
392  else
393  wl = cctowl(cc->cc_child, true);
394  if (sib) {
395  if (wl) {
396  for (end = wl; end->wl_next; end = end->wl_next)
397  ;
398  end->wl_next = cctowl(cc->cc_sibling, true);
399  if (end->wl_next)
400  end->wl_next->wl_prev = wl;
401  }
402  else
403  wl = cctowl(cc->cc_sibling, true);
404  }
405  return (wl);
406 }
407 
408 
409 /* We use this in com_device... */
410 
411 wordlist *
412 cp_cctowl(stuff)
413 
414 char *stuff;
415 {
416  return (cctowl((struct ccom *) stuff, true));
417 }
418 
419 
420 /* Turn on and off the escape break character and cooked mode. */
421 
422 void
424 
425 bool on;
426 {
427 #ifdef TIOCSTI
428 
429 #ifdef HAVE_TERMIOS_H
430 
431 #define TERM_GET TCGETS
432 #define TERM_SET TCSETS
433  static struct termios sbuf;
434  static struct termios OS_Buf;
435 
436 #else
437 
438 #ifdef HAVE_TERMIO_H
439 
440 #define TERM_GET TCGETA
441 #define TERM_SET TCSETA
442  static struct termio sbuf;
443  static struct termio OS_Buf;
444 
445 #else
446 #ifdef HAVE_SGTTY_H
447  static bool ison = false;
448  struct tchars tbuf;
449  struct sgttyb sbuf;
450 
451  if (cp_nocc || !cp_interactive || (ison == on))
452  return;
453  ison = on;
454 
455  /* Set the terminal up -- make escape the break character, and
456  * make sure we aren't in raw or cbreak mode. Hope the (void) ioctl's
457  * won't fail.
458  */
459  (void) ioctl(fileno(cp_in), TIOCGETC, (char *) &tbuf);
460  if (on)
461  tbuf.t_brkc = ESCAPE;
462  else
463  tbuf.t_brkc = '\0';
464  (void) ioctl(fileno(cp_in), TIOCSETC, (char *) &tbuf);
465 
466  (void) ioctl(fileno(cp_in), TIOCGETP, (char *) &sbuf);
467  sbuf.sg_flags &= ~(RAW|CBREAK);
468  (void) ioctl(fileno(cp_in), TIOCSETP, (char *) &sbuf);
469 
470 #endif
471 #endif
472 
473 #ifdef TERM_GET
474  static bool ison = false;
475 
476  if (cp_nocc || !cp_interactive || (ison == on))
477  return;
478  ison = on;
479 
480  if (ison == true) {
481  (void) ioctl(fileno(cp_in), TERM_GET, (char *) &OS_Buf);
482  sbuf = OS_Buf;
483  sbuf.c_cc[VEOF] = 0;
484  sbuf.c_cc[VEOL] = ESCAPE;
485  sbuf.c_cc[VEOL2] = CNTRL_D;
486  (void) ioctl(fileno(cp_in), TERM_SET, (char *) &sbuf);
487  }
488  else {
489  (void) ioctl(fileno(cp_in), TERM_SET, (char *) &OS_Buf);
490  }
491 
492 #endif
493 #endif
494 
495 #endif
496 
497  return;
498 }
499 
500 
501 /* The following routines deal with the command and keyword databases.
502  * Say whether a given word exists in the command database.
503  */
504 
505 bool
507 
508 char *word;
509 {
510  if (word && *word && clookup(word, &commands, false, false))
511  return (true);
512  else
513  return (false);
514 }
515 
516 
517 /* Add a command to the database, with the given keywords and filename flag. */
518 
519 void
520 cp_addcomm(word, bits0, bits1, bits2, bits3)
521 
522 char *word;
523 long bits0, bits1, bits2, bits3;
524 {
525  struct ccom *cc;
526 
527  if (cp_nocc)
528  return;
529 
530  cc = clookup(word, &commands, false, true);
531  cc->cc_invalid = 0;
532  cc->cc_kwords[0] = bits0;
533  cc->cc_kwords[1] = bits1;
534  cc->cc_kwords[2] = bits2;
535  cc->cc_kwords[3] = bits3;
536  return;
537 }
538 
539 
540 /* Remove a command from the database. */
541 
542 void
544 
545 char *word;
546 {
547  struct ccom *cc;
548 
549  cc = clookup(word, &commands, false, false);
550  if (cc)
551  cdelete(cc);
552  return;
553 }
554 
555 
556 /* Add a keyword to the database. */
557 
558 void
559 cp_addkword(class, word)
560 
561 int class;
562 char *word;
563 {
564  struct ccom *cc;
565 
566  if (cp_nocc)
567  return;
568 
569  if ((class < 1) || (class >= NCLASSES)) {
570  fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n",
571  class);
572  return;
573  }
574  cc = clookup(word, &keywords[class], false, true);
575  cc->cc_invalid = 0;
576  return;
577 }
578 
579 
580 /* Remove a keyword from the database. */
581 
582 void
583 cp_remkword(class, word)
584 
585 char *word;
586 {
587  struct ccom *cc;
588 
589  if ((class < 1) || (class >= NCLASSES)) {
590  fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n",
591  class);
592  return;
593  }
594  cc = clookup(word, &keywords[class], false, false);
595  if (cc)
596  cdelete(cc);
597  return;
598 }
599 
600 
601 /* This routine is used when there are several keyword sets that are
602  * to be switched between rapidly. The return value is the old tree at
603  * that position, and the keyword class given is set to the argument.
604  */
605 
606 char *
607 cp_kwswitch(class, tree)
608 
609 int class;
610 char *tree;
611 {
612  char *old;
613 
614  if ((class < 1) || (class >= NCLASSES)) {
615  fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n",
616  class);
617  return (NULL);
618  }
619  old = (char *) keywords[class];
620  keywords[class] = (struct ccom *) tree;
621  return (old);
622 }
623 
624 
625 void
627 
628 char *pntr;
629 {
630  int i;
631  struct ccom *dbase = (struct ccom*)pntr;
632 
633  if (dbase == commands) commands = NULL;
634  for (i = 0; i < NCLASSES; i++)
635  if (dbase == keywords[i])
636  keywords[i] = NULL;
637 
638  throwaway(dbase);
639 }
640 
641 
642 /* Throw away all the stuff and prepare to rebuild it from scratch... */
643 
644 void
646 
647 bool kwords;
648 {
649  int i;
650 
651  throwaway(commands);
652  commands = NULL;
653 
654  if (kwords)
655  for (i = 0; i < NCLASSES; i++) {
656  throwaway(keywords[i]);
657  keywords[i] = NULL;
658  }
659  return;
660 }
661 
662 
663 static void
664 throwaway(dbase)
665 
666 struct ccom *dbase;
667 {
668  if (dbase == NULL) return;
669  if (dbase->cc_child)
670  throwaway(dbase->cc_child);
671  if (dbase->cc_sibling)
672  throwaway(dbase->cc_sibling);
673  tfree(dbase->cc_name);
674  tfree(dbase);
675  return;
676 }
677 
678 
679 /* Look up a word in the database. Because of the
680  * way the tree is set up, this also works for looking up all words with
681  * a given prefix (if the pref arg is true). If create is true, then the
682  * node is created if it doesn't already exist.
683  */
684 
685 static struct ccom *
686 clookup(word, dd, pref, create)
687 
688 char *word;
689 struct ccom **dd;
690 bool pref;
691 bool create;
692 {
693  struct ccom *place = *dd, *tmpc;
694  int ind = 0, i;
695  char buf[BSIZE_SP];
696 
697  if (!word || !*word) return place;
698 
699  if (!place) {
700  /* This is the first time we were called. */
701  if (!create)
702  return (NULL);
703 
704  *dd = place = alloc(struct ccom);
705  buf[0] = *word;
706  buf[1] = '\0';
707  place->cc_name = copy(buf);
708  if (word[1])
709  place->cc_invalid = 1;
710 
711  }
712  while (word[ind]) {
713  /* Walk down the sibling list until we find a node that
714  * matches 'word' to 'ind' places.
715  */
716  while ((place->cc_name[ind] < word[ind]) && place->cc_sibling)
717  place = place->cc_sibling;
718  if (place->cc_name[ind] < word[ind]) {
719 
720  /* This line doesn't go out that far... */
721  if (!create)
722  return (NULL);
723 
724  place->cc_sibling = alloc(struct ccom);
725  place->cc_sibling->cc_ysibling = place;
726  place->cc_sibling->cc_parent = place->cc_parent;
727  place = place->cc_sibling;
728  place->cc_name = tmalloc(ind + 2);
729  for (i = 0; i < ind + 1; i++)
730  place->cc_name[i] = word[i];
731  place->cc_name[ind + 1] = '\0';
732  place->cc_invalid = 1;
733  }
734  else if (place->cc_name[ind] > word[ind]) {
735  if (!create)
736  return (NULL);
737 
738  /* Put this one between place and its pred. */
739  tmpc = alloc(struct ccom);
740  tmpc->cc_parent = place->cc_parent;
741  tmpc->cc_sibling = place;
742  tmpc->cc_ysibling = place->cc_ysibling;
743  place->cc_ysibling = tmpc;
744  place = tmpc;
745  if (tmpc->cc_ysibling)
746  tmpc->cc_ysibling->cc_sibling = tmpc;
747  else if (tmpc->cc_parent)
748  tmpc->cc_parent->cc_child = tmpc;
749  else
750  *dd = place;
751  place->cc_name = tmalloc(ind + 2);
752  for (i = 0; i < ind + 1; i++)
753  place->cc_name[i] = word[i];
754  place->cc_name[ind + 1] = '\0';
755  place->cc_invalid = 1;
756  }
757 
758  /* place now points to that node that matches the word for
759  * ind + 1 characters.
760  */
761 /* printf("place %s, word %s, ind %d\n", place->cc_name, word, ind); */
762  if (word[ind + 1]) { /* More to go... */
763  if (!place->cc_child) {
764 
765  /* No children, maybe make one and go on. */
766  if (!create)
767  return (NULL);
768 
769  tmpc = alloc(struct ccom);
770  tmpc->cc_parent = place;
771  place->cc_child = tmpc;
772  place = tmpc;
773  place->cc_name = tmalloc(ind + 3);
774  for (i = 0; i < ind + 2; i++)
775  place->cc_name[i] = word[i];
776  place->cc_name[ind + 2] = '\0';
777  if (word[ind + 2])
778  place->cc_invalid = 1;
779  }
780  else
781  place = place->cc_child;
782  ind++;
783  }
784  else
785  break;
786  }
787  if (!pref && !create && place->cc_invalid) {
788  /* This is no good, we want a real word. */
789  return (NULL);
790  }
791  return (place);
792 }
793 
794 
795 /* Delete a node from the tree. Returns the new tree... */
796 
797 static void
798 cdelete(node)
799 
800 struct ccom *node;
801 {
802  node->cc_invalid = 1;
803  return;
804 }
805 
static char buf[MAXPROMPT]
Definition: arg.c:18
#define BSIZE_SP
Definition: misc.h:19
#define NARGS
Definition: complete.c:53
#define eq(a, b)
Definition: misc.h:29
Definition: subckt.c:18
#define CNTRL_D
Definition: complete.c:50
int wl_length()
char * cp_tildexpand()
#define prefix(x, y)
Definition: readhelp.c:39
void out_printf()
char * strcpy()
Definition: cddefs.h:119
if(TDesc==NULL)
Definition: cd.c:1326
struct alias * al_next
Definition: cpdefs.h:60
void cp_remkword(class, char *word)
Definition: complete.c:583
char * al_name
Definition: cpdefs.h:58
struct alias * cp_aliases
Definition: alias.c:22
static void throwaway()
struct ccom * cc_parent
Definition: complete.c:91
Definition: complete.c:84
bool cp_nocc
Definition: complete.c:75
bool cp_comlook(char *word)
Definition: complete.c:506
Definition: library.c:18
int bool
Definition: cpstd.h:16
#define alloc(type)
Definition: cdmacs.h:21
void cp_unquote()
char * copy()
char * cc_name
Definition: complete.c:85
#define NCLASSES
Definition: complete.c:52
static struct ccom * getccom()
void wl_free()
void cp_ccom(wordlist *wlist, char *buf, bool esc)
Definition: complete.c:365
FILE * cp_err
Definition: help.c:101
static struct ccom * clookup()
char * tmalloc()
struct ccom * cc_child
Definition: complete.c:88
struct wordlist * wl_prev
Definition: cpstd.h:24
wordlist * al_text
Definition: cpdefs.h:59
void cp_remcomm(char *word)
Definition: complete.c:543
char cc_invalid
Definition: complete.c:87
bool cp_interactive
Definition: help.c:100
#define tfree(x)
Definition: cdmacs.h:22
wordlist * wl_nthelem()
void txfree()
#define NULL
Definition: spdefs.h:121
FILE * cp_out
Definition: help.c:101
static void cdelete()
Definition: sced.h:120
static int lcomp()
void cp_ccrestart(bool kwords)
Definition: complete.c:645
wordlist * wl_append()
static wordlist * cctowl()
void cp_addkword(int class, char *word)
Definition: complete.c:559
Definition: cpstd.h:21
struct ccom * cc_sibling
Definition: complete.c:89
static wordlist * ccmatch()
static struct ccom * commands
Definition: complete.c:94
Definition: netlist.c:477
static wordlist * ccfilec()
long cc_kwords[NARGS]
Definition: complete.c:86
void out_send()
struct wordlist * wl_next
Definition: cpstd.h:23
wordlist * cp_cctowl(char *stuff)
Definition: complete.c:412
static struct ccom * keywords[NCLASSES]
Definition: complete.c:95
char * wl_word
Definition: cpstd.h:22
void wl_sort()
void out_winsize()
void cp_ccfreetrie(char *pntr)
Definition: complete.c:626
char cp_til
Definition: glob.c:58
struct ccom * cc_ysibling
Definition: complete.c:90
#define ESCAPE
Definition: complete.c:51
FILE * cp_in
Definition: help.c:101
void cp_addcomm(char *word, long bits0, long bits1, long bits2, long bits3)
Definition: complete.c:520
Definition: cpdefs.h:57
static void printem()
Definition: cddefs.h:192
void cp_wstrip()
char * cp_kwswitch(int class, char *tree)
Definition: complete.c:607
void cp_ccon(bool on)
Definition: complete.c:423
void out_init()
Definition: output.c:128