📄 complete.c
字号:
wordlist *cp_cctowl(char *stuff){ return (cctowl((struct ccom *) stuff, TRUE));}/* Turn on and off the escape break character and cooked mode. */voidcp_ccon(bool on){#ifdef TIOCSTI#ifdef HAVE_SGTTY_H static bool ison = FALSE; struct tchars tbuf; struct sgttyb sbuf; if (cp_nocc || !cp_interactive || (ison == on)) return; ison = on; /* Set the terminal up -- make escape the break character, and * make sure we aren't in raw or cbreak mode. Hope the (void) * ioctl's won't fail. */ (void) ioctl(fileno(cp_in), TIOCGETC, (char *) &tbuf); if (on) tbuf.t_brkc = ESCAPE; else tbuf.t_brkc = '\0'; (void) ioctl(fileno(cp_in), TIOCSETC, (char *) &tbuf); (void) ioctl(fileno(cp_in), TIOCGETP, (char *) &sbuf); sbuf.sg_flags &= ~(RAW|CBREAK); (void) ioctl(fileno(cp_in), TIOCSETP, (char *) &sbuf);#else# ifdef HAVE_TERMIO_H# define TERM_GET TCGETA# define TERM_SET TCSETA static struct termio sbuf; static struct termio OS_Buf;# else# ifdef HAVE_TERMIOS_H# define TERM_GET TCGETS# define TERM_SET TCSETS static struct termios sbuf; static struct termios OS_Buf;# endif# endif#ifdef TERM_GET static bool ison = FALSE; if (cp_nocc || !cp_interactive || (ison == on)) return; ison = on; if (ison == TRUE) {#if HAVE_TCGETATTR tcgetattr(fileno(cp_in),&OS_Buf);#else (void) ioctl(fileno(cp_in), TERM_GET, (char *) &OS_Buf);#endif sbuf = OS_Buf; sbuf.c_cc[VEOF] = 0; sbuf.c_cc[VEOL] = ESCAPE; sbuf.c_cc[VEOL2] = CNTRL_D;#if HAVE_TCSETATTR tcsetattr(fileno(cp_in),TCSANOW,&sbuf);#else (void) ioctl(fileno(cp_in), TERM_SET, (char *) &sbuf);#endif } else {#ifdef HAVE_TCSETATTR tcsetattr(fileno(cp_in),TCSANOW,&OS_Buf);#else (void) ioctl(fileno(cp_in), TERM_SET, (char *) &OS_Buf);#endif }# endif#endif#endif return;}/* The following routines deal with the command and keyword databases. * Say whether a given word exists in the command database. */boolcp_comlook(char *word){ if (word && *word && clookup(word, &commands, FALSE, FALSE)) return (TRUE); else return (FALSE);}/* Add a command to the database, with the given keywords and filename * flag. */voidcp_addcomm(char *word, long int bits0, long int bits1, long int bits2, long int bits3){ struct ccom *cc; cc = clookup(word, &commands, FALSE, TRUE); cc->cc_invalid = 0; cc->cc_kwords[0] = bits0; cc->cc_kwords[1] = bits1; cc->cc_kwords[2] = bits2; cc->cc_kwords[3] = bits3; return;}/* Remove a command from the database. */voidcp_remcomm(char *word){ struct ccom *cc; cc = clookup(word, &commands, FALSE, FALSE); if (cc) cdelete(cc, &commands); return;}/* Add a keyword to the database. */voidcp_addkword(int class, char *word){ struct ccom *cc; if ((class < 1) || (class >= NCLASSES)) { fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n", class); return; }/* word = copy(word); va: not necessary, clookup copies itself (memory leak) */ cc = clookup(word, &keywords[class], FALSE, TRUE); cc->cc_invalid = 0; return;}/* Remove a keyword from the database. */voidcp_remkword(int class, char *word){ struct ccom *cc; if ((class < 1) || (class >= NCLASSES)) { fprintf(cp_err, "cp_remkword: Internal Error: bad class %d\n", class); return; } cc = clookup(word, &keywords[class], FALSE, FALSE); if (cc) cdelete(cc, &keywords[class]); return;}/* This routine is used when there are several keyword sets that are * to be switched between rapidly. The return value is the old tree at * that position, and the keyword class given is set to the argument. */char *cp_kwswitch(int class, char *tree){ char *old; if ((class < 1) || (class >= NCLASSES)) { fprintf(cp_err, "cp_addkword: Internal Error: bad class %d\n", class); return (NULL); } old = (char *) keywords[class]; keywords[class] = (struct ccom *) tree; return (old);}/* Throw away all the stuff and prepare to rebuild it from scratch... */voidcp_ccrestart(bool kwords){ /* Ack. */ return;}voidthrowaway(struct ccom *dbase){ if (!dbase) return; /* va: security first */ if (dbase->cc_child) throwaway(dbase->cc_child); if (dbase->cc_sibling) throwaway(dbase->cc_sibling); tfree(dbase->cc_name); /* va: also tfree dbase->cc_name (memory leak) */ tfree(dbase); return;}/* Look up a word in the database. Because of the way the tree is set * up, this also works for looking up all words with a given prefix * (if the pref arg is TRUE). If create is TRUE, then the node is * created if it doesn't already exist. */static struct ccom *clookup(register char *word, struct ccom **dd, bool pref, bool create){ register struct ccom *place = *dd, *tmpc; int ind = 0, i; char buf[BSIZE_SP]; if (!place) { /* This is the first time we were called. */ if (!create) return (NULL); else { *dd = place = alloc(struct ccom); ZERO(place, struct ccom); buf[0] = *word; buf[1] = '\0'; place->cc_name = copy(buf); if (word[1]) place->cc_invalid = 1; } } while (word[ind]) { /* Walk down the sibling list until we find a node that * matches 'word' to 'ind' places. */ while ((place->cc_name[ind] < word[ind]) && place->cc_sibling) place = place->cc_sibling; if (place->cc_name[ind] < word[ind]) { /* This line doesn't go out that far... */ if (create) { place->cc_sibling = alloc(struct ccom); ZERO(place->cc_sibling, struct ccom); place->cc_sibling->cc_ysibling = place; place->cc_sibling->cc_parent = place->cc_parent; place = place->cc_sibling; place->cc_name = tmalloc(ind + 2); for (i = 0; i < ind + 1; i++) place->cc_name[i] = word[i]; place->cc_name[ind + 1] = '\0'; place->cc_invalid = 1; } else { return (NULL); } } else if (place->cc_name[ind] > word[ind]) { if (create) { /* Put this one between place and its pred. */ tmpc = alloc(struct ccom); ZERO(tmpc, struct ccom); tmpc->cc_parent = place->cc_parent; tmpc->cc_sibling = place; tmpc->cc_ysibling = place->cc_ysibling; place->cc_ysibling = tmpc; place = tmpc; if (tmpc->cc_ysibling) tmpc->cc_ysibling->cc_sibling = tmpc; else if (tmpc->cc_parent) tmpc->cc_parent->cc_child = tmpc; else *dd = place; place->cc_name = tmalloc(ind + 2); for (i = 0; i < ind + 1; i++) place->cc_name[i] = word[i]; place->cc_name[ind + 1] = '\0'; place->cc_invalid = 1; } else { return (NULL); } } /* place now points to that node that matches the word for * ind + 1 characters. */ if (word[ind + 1]) { /* More to go... */ if (!place->cc_child) { /* No children, maybe make one and go on. */ if (create) { tmpc = alloc(struct ccom); ZERO(tmpc, struct ccom); tmpc->cc_parent = place; place->cc_child = tmpc; place = tmpc; place->cc_name = tmalloc(ind + 3); for (i = 0; i < ind + 2; i++) place->cc_name[i] = word[i]; place->cc_name[ind + 2] = '\0'; if (word[ind + 2]) place->cc_invalid = 1; } else { return (NULL); } } else place = place->cc_child; ind++; } else break; } if (!pref && !create && place->cc_invalid) { /* This is no good, we want a real word. */ return (NULL); } return (place);}/* Delete a node from the tree. Returns the new tree... *//* MW. It is quite difficoult to free() everything right, but... * Anyway this could be more optimal, I think */static voidcdelete(struct ccom *node, struct ccom **top){ /* if cc_child exist only mark as deleted */ node->cc_invalid = 1; if (node->cc_child) return; /* fix cc_sibling */ if (node->cc_sibling) node->cc_sibling->cc_ysibling = node->cc_ysibling; if (node->cc_ysibling) node->cc_ysibling->cc_sibling = node->cc_sibling; /* if we have cc_parent, check if it should not be removed too */ if (node->cc_parent) { /* this node will be free() */ if (node->cc_parent->cc_child == node) { if (node->cc_ysibling) node->cc_parent->cc_child = node->cc_ysibling; else node->cc_parent->cc_child = node->cc_sibling; } if (node->cc_parent->cc_invalid == 1) /* free parent only if it is invalid */ cdelete(node->cc_parent, top); } /* now free() everything and check the top */ if (node == *top) *top = node->cc_sibling; tfree(node->cc_name); /* va: we should allways use tfree */ tfree(node); return;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -