da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
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* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * completion.c - command and file completion for shell editors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ast_wchar.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "lexstates.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "edit.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if !SHOPT_MULTIBYTE
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define mbchar(p) (*(unsigned char*)p++)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic char *fmtx(const char *string)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register const char *cp = string;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register int n,c;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unsigned char *state = (unsigned char*)sh_lexstates[2];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int offset;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while((c=mbchar(cp)),(c>UCHAR_MAX)||(n=state[c])==0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(n==S_EOF)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return((char*)string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz offset = staktell();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakwrite(string,--cp-string);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while(c=mbchar(cp))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(state[c])
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakputc('\\');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakputc(c);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz stakputc(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(stakptr(offset));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int charcmp(int a, int b, int nocase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nocase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isupper(a))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin a = tolower(a);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isupper(b))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin b = tolower(b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(a==b);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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>)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *overlaid(register char *str,register const char *newstr,int nocase)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *(unsigned char *)str) && ((d= *(unsigned char*)newstr++),charcmp(c,d,nocase)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *str = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*newstr==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns pointer to beginning of expansion and sets type of expansion
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *find_begin(char outbuff[], char *last, int endchar, int *type)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp=outbuff, *bp, *xp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c,inquote = 0, inassign=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int mode=*type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = outbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *type = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp < last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(c= mbchar(cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\'': case '"':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!inquote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inquote==c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin inquote = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '\\':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inquote != '\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbchar(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '$':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inquote == '\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode!='*' && (isaletter(c) || c=='{'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int dot = '.';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbchar(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!='.' && !isaletter(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot = 'a';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp < last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c= mbchar(cp)) , c!=dot && !isaname(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp>=last && c!= '}')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *type='$';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(++xp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *type = mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = find_begin(cp,last,')',type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*(cp=xp)!=')')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = xp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '=':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!inquote)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin inassign = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ':':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!inquote && inassign)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '~':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='(')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* fall through */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c && c==endchar)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(xp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!inquote && ismeta(c))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bp = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin inassign = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(inquote && *bp==inquote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *type = *bp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
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
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_expand(Edit_t *ep, char outbuff[],int *cur,int *eol,int mode, int count)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct comnod *comptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *av[2], *begin , *dir=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int addstar=0, rval=0, var=0, strip=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nomarkdirs = !sh_isoption(SH_MARKDIRS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_FCOMPLETE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_nlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode=='=' && count>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(count> ep->e_nlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = '?';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[0] = ep->e_clist[count-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(ep->e_stkptr,ep->e_stkoff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_nlist = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comptr = (struct comnod*)stakalloc(sizeof(struct comnod));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = (struct argnod*)stakseek(ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c = *cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register genchar *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* adjust cur */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (genchar *)outbuff + *cur;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cur = ed_external((genchar*)outbuff,(char*)stakptr(0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *eol = ed_external((genchar*)outbuff,outbuff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = outbuff + *cur + (sh_isoption(SH_VI)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comptr->comtyp = COMSCAN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin comptr->comarg = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag = (ARG_MAC|ARG_EXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argnxt.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argchn.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *last = out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)out;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin var = mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin = out = find_begin(outbuff,last,0,&var);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* addstar set to zero if * should not be added */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(var=='$')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("${!");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakwrite(out,last-out);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs("@}");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addstar = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(out < last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isexp(c))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addstar = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (c == '/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(addstar == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strip = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dir = out+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode=='?')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mode = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(var!='$' && mode=='\\' && out[-1]!='*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addstar = '*';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*begin=='~' && !strchr(begin,'/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin addstar = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(addstar);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = (struct argnod*)stakfreeze(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!='*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onoption(SH_MARKDIRS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **com;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp=begin, *left=0, *saveout=".";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nocase=0,narg,cmd_completion=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size='x';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(cp>outbuff && ((size=cp[-1])==' ' || size=='\t'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!var && !strchr(ap->argval,'/') && (((cp==outbuff&&sh.nextprompt==1) || (strchr(";&|(",size)) && (cp==outbuff+1||size=='('||cp[-2]!='>') && *begin!='~' )))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cmd_completion=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_COMPLETE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_nlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin narg = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com = av;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dir)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin += (dir-begin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin com = sh_argbuild(ep->sh,&narg,comptr,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special handling for leading quotes */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(begin>outbuff && (begin[-1]=='"' || begin[-1]=='\''))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin begin--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_COMPLETE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* allow a search to be aborted */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote&SH_SIGSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rval = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* match? */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*com==0 || (narg <= 1 && (strcmp(ap->argval,*com)==0) || (addstar && com[0][strlen(*com)-1]=='*')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rval = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (strip && !cmd_completion)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **ptrcom;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(ptrcom=com;*ptrcom;ptrcom++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* trim directory prefix */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ptrcom = path_basename(*ptrcom);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstderr,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_menu(sfstderr,narg,com);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_nlist = narg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_clist = com;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if there is enough room */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = *eol - (out-begin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dir)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *dir;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dir = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin saveout = begin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(saveout=astconf("PATH_ATTRIBUTES",saveout,(char*)0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nocase = (strchr(saveout,'c')!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dir)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *dir = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* just expand until name is unique */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size += strlen(*com);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size += narg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **savcom = com;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*com)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz size += strlen(cp=fmtx(*com++));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com = savcom;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if room for expansion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(outbuff+size >= &outbuff[MAXLINE])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com[0] = ap->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save remainder of the buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*out)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left=stakcopy(out);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cmd_completion && mode=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,path_basename(cp= *com++));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode=='*')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_nlist && dir && var)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp==var)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *begin++ = var;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin var = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz out = strcopy(begin,fmtx(*com));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin com++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,*com++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode=='\\')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin saveout= ++out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*com && *begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cmd_completion)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = overlaid(begin,path_basename(*com++),nocase);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = overlaid(begin,*com++,nocase);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = (out==saveout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(out[-1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode && out[-1]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cmd_completion)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add as tracked alias */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Pathcomp_t *pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*cp=='/' && (pp=path_dirfind(sh.pathlist,cp,'/')) && (np=nv_search(begin,sh.track_tree,NV_ADD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path_alias(np,pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* add quotes if necessary */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((cp=fmtx(begin))!=begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(var=='$' && begin[-1]=='{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out = '}';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *++out = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if((cp=fmtx(begin))!=begin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(begin,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(out[-1] =='"' || out[-1]=='\'')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *--out = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*begin==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_ringbell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while (*com)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out++ = ' ';
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz out = strcopy(out,fmtx(*com++));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_nlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = com[-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp[strlen(cp)-1]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(var=='$' && begin[-1]=='{')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out = '}';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out = ' ';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(out[-1] =='"' || out[-1]=='\'')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *out = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cur = (out-outbuff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore rest of buffer */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = strcopy(out,left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *eol = (out-outbuff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_FCOMPLETE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->e_nlist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakset(ep->e_stkptr,ep->e_stkoff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nomarkdirs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offoption(SH_MARKDIRS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c,n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* first re-adjust cur */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = outbuff[*cur];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outbuff[*cur] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(out=outbuff; *out;n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mbchar(out);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outbuff[*cur] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cur = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin outbuff[*eol+1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *eol = ed_internal(outbuff,(genchar*)outbuff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(rval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * look for edit macro named _i
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if found, puts the macro definition into lookahead buffer and returns 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_macro(Edit_t *ep, register int i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin genchar buff[LOOKAHEAD+1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i != '@')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_macro[1] = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* undocumented feature, macros of the form <ESC>[c evoke alias __c */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i=='_')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_macro[2] = ed_getchar(ep,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_macro[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (isalnum(i)&&(np=nv_search(ep->e_macro,sh.alias_tree,HASH_SCOPE))&&(out=nv_getval(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy to buff in internal representation */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int c = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( strlen(out) > LOOKAHEAD )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = out[LOOKAHEAD];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out[LOOKAHEAD] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = ed_internal(out,buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out[LOOKAHEAD] = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strncpy((char*)buff,out,LOOKAHEAD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin buff[LOOKAHEAD] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = strlen((char*)buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(i-- > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_ungetchar(ep,buff[i]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Enter the fc command on the current history line
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint ed_fulledit(Edit_t *ep)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.hist_ptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* use EDITOR on current command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_hline == ep->e_hismax)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ep->e_eol<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_MULTIBYTE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_inbuf[ep->e_eol+1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ed_external(ep->e_inbuf, (char *)ep->e_inbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sh.hist_ptr->histfp,(char*)ep->e_inbuf,ep->e_eol+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_HISTORY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hist_flush(sh.hist_ptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = strcopy((char*)ep->e_inbuf,e_runvi);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = strcopy(cp, fmtbase((long)ep->e_hline,10,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->e_eol = ((unsigned char*)cp - (unsigned char*)ep->e_inbuf)-(sh_isoption(SH_VI)!=0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}