da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * completion.c - command and file completion for shell editors
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int n,c;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char *state = (unsigned char*)sh_lexstates[2];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while((c=mbchar(cp)),(c>UCHAR_MAX)||(n=state[c])==0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return((char*)string);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(a==b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * overwrites <str> to common prefix of <str> and <newstr>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <str> is equal to <newstr> returns <str>+strlen(<str>)+1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise returns <str>+strlen(<str>)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *overlaid(register char *str,register const char *newstr,int nocase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *(unsigned char *)str) && ((d= *(unsigned char*)newstr++),charcmp(c,d,nocase)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*newstr==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns pointer to beginning of expansion and sets type of expansion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *find_begin(char outbuff[], char *last, int endchar, int *type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(++xp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* fall through */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c && c==endchar)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * file name generation for edit modes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * non-zero exit for error, <0 ring bell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * don't search back past beginning of the buffer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode is '*' for inline expansion,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode is '\' for filename completion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode is '=' cause files to be listed in select format
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comptr = (struct comnod*)stakalloc(sizeof(struct comnod));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c = *cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* adjust cur */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cur = ed_external((genchar*)outbuff,(char*)stakptr(0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* addstar set to zero if * should not be added */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!var && !strchr(ap->argval,'/') && (((cp==outbuff&&sh.nextprompt==1) || (strchr(";&|(",size)) && (cp==outbuff+1||size=='('||cp[-2]!='>') && *begin!='~' )))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special handling for leading quotes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* allow a search to be aborted */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* match? */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*com==0 || (narg <= 1 && (strcmp(ap->argval,*com)==0) || (addstar && com[0][strlen(*com)-1]=='*')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* trim directory prefix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if there is enough room */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(saveout=astconf("PATH_ATTRIBUTES",saveout,(char*)0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* just expand until name is unique */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if room for expansion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save remainder of the buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add as tracked alias */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='/' && (pp=path_dirfind(sh.pathlist,cp,'/')) && (np=nv_search(begin,sh.track_tree,NV_ADD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add quotes if necessary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore rest of buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first re-adjust cur */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * look for edit macro named _i
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if found, puts the macro definition into lookahead buffer and returns 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i != '@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* undocumented feature, macros of the form <ESC>[c evoke alias __c */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i=='_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalnum(i)&&(np=nv_search(ep->e_macro,sh.alias_tree,HASH_SCOPE))&&(out=nv_getval(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy to buff in internal representation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(i-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Enter the fc command on the current history line
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* use EDITOR on current command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sh.hist_ptr->histfp,(char*)ep->e_inbuf,ep->e_eol+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eol = ((unsigned char*)cp - (unsigned char*)ep->e_inbuf)-(sh_isoption(SH_VI)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);