Exemple #1
0
/*
 * change '['identifier']' to identifier
 * character before <str> must be a '['
 * returns pointer to last character
 */
char *sh_checkid(char *str, char *last)
{
	register unsigned char *cp = (unsigned char*)str;
	register unsigned char *v = cp;
	register int c;
	if(c= *cp++,isaletter(c))
		while(c= *cp++,isaname(c));
	if(c==']' && (!last || ((char*)cp==last)))
	{
		/* eliminate [ and ] */
		while(v < cp)
		{
			v[-1] = *v;
			v++;
		}
		if(last)
			last -=2;
		else
		{
			while(*v)
			{
				v[-2] = *v;
				v++;
			}
			v[-2] = 0;
			last = (char*)v;
		}
	}
	return(last);
}
Exemple #2
0
/*
 * returns pointer to beginning of expansion and sets type of expansion
 */
static char *find_begin(char outbuff[], char *last, int endchar, int *type)
{
	register char	*cp=outbuff, *bp, *xp;
	register int 	c,inquote = 0, inassign=0;
	int		mode=*type;
	bp = outbuff;
	*type = 0;
	while(cp < last)
	{
		xp = cp;
		switch(c= mbchar(cp))
		{
		    case '\'': case '"':
			if(!inquote)
			{
				inquote = c;
				bp = xp;
				break;
			}
			if(inquote==c)
				inquote = 0;
			break;
		    case '\\':
			if(inquote != '\'')
				mbchar(cp);
			break;
		    case '$':
			if(inquote == '\'')
				break;
			c = *(unsigned char*)cp;
			if(mode!='*' && (isaletter(c) || c=='{'))
			{
				int dot = '.';
				if(c=='{')
				{
					xp = cp;
					mbchar(cp);
					c = *(unsigned char*)cp;
					if(c!='.' && !isaletter(c))
						break;
				}
				else
					dot = 'a';
				while(cp < last)
				{
					if((c= mbchar(cp)) , c!=dot && !isaname(c))
						break;
				}
				if(cp>=last)
				{
					if(c==dot || isaname(c))
					{
						*type='$';
						return(++xp);
					}
					if(c!='}')
						bp = cp;
				}
			}
			else if(c=='(')
			{
				*type = mode;
				xp = find_begin(cp,last,')',type);
				if(*(cp=xp)!=')')
					bp = xp;
				else
					cp++;
			}
			break;
		    case '=':
			if(!inquote)
			{
				bp = cp;
				inassign = 1;
			}
			break;
		    case ':':
			if(!inquote && inassign)
				bp = cp;
			break;
		    case '~':
			if(*cp=='(')
				break;
			/* fall through */
		    default:
			if(c && c==endchar)
				return(xp);
			if(!inquote && ismeta(c))
			{
				bp = cp;
				inassign = 0;
			}
			break;
		}
	}
	if(inquote && *bp==inquote)
		*type = *bp++;
	return(bp);
}
Exemple #3
0
//
// Returns pointer to beginning of expansion and sets type of expansion.
//
static char *find_begin(char outbuff[], char *last, int endchar, int *type) {
    char *cp = outbuff, *bp, *xp;
    int c, inquote = 0, inassign = 0;
    int mode = *type;

    bp = outbuff;
    *type = 0;
    while (cp < last) {
        xp = cp;
        switch (c = mb1char(&cp)) {
            case '\'':
            case '"': {
                if (!inquote) {
                    inquote = c;
                    bp = xp;
                    break;
                }
                if (inquote == c) inquote = 0;
                break;
            }
            case '\\': {
                if (inquote != '\'') (void)mb1char(&cp);
                break;
            }
            case '$': {
                if (inquote == '\'') break;
                c = *(unsigned char *)cp;
                if (mode != '*' && (isaletter(c) || c == '{')) {
                    int dot = '.';
                    if (c == '{') {
                        xp = cp;
                        (void)mb1char(&cp);
                        c = *(unsigned char *)cp;
                        if (c != '.' && !isaletter(c)) break;
                    } else {
                        dot = 'a';
                    }
                    while (cp < last) {
                        if ((c = mb1char(&cp)), c != dot && !isaname(c)) break;
                    }
                    if (cp >= last) {
                        if (c == dot || isaname(c)) {
                            *type = '$';
                            return ++xp;
                        }
                        if (c != '}') bp = cp;
                    }
                } else if (c == '(') {
                    *type = mode;
                    xp = find_begin(cp, last, ')', type);
                    if (*(cp = xp) != ')') {
                        bp = xp;
                    } else {
                        cp++;
                    }
                }
                break;
            }
            case '=': {
                if (!inquote) {
                    bp = cp;
                    inassign = 1;
                }
                break;
            }
            case ':': {
                if (!inquote && inassign) bp = cp;
                break;
            }
            case '~': {
                if (*cp == '(') break;
            }
            // FALLTHRU
            default: {
                if (c && c == endchar) return xp;
                if (!inquote && ismeta(c)) {
                    bp = cp;
                    inassign = 0;
                }
                break;
            }
        }
    }
    if (inquote && *bp == inquote) {
        *type = *bp++;
    } else {
        if (*cp == 0 && cp[-1] == ' ') return cp;
    }
    return bp;
}
Exemple #4
0
/*
 * print <str> quoting chars so that it can be read by the shell
 * puts null terminated result on stack, but doesn't freeze it
 * single!=0 limits quoting to '...'
 * fold>0 prints raw newlines and inserts appropriately
 * escaped newlines every (fold-x) chars
 */
char	*sh_fmtqf(const char *string, int single, int fold)
{
	register const char *cp = string;
	register const char *bp;
	register const char *vp;
	register int c;
	register int n;
	register int q;
	register int a;
	int offset;

	if (--fold < 8)
		fold = 0;
	if (!cp || !*cp || !single && !fold || fold && strlen(string) < fold)
		return sh_fmtq(cp);
	offset = staktell();
	single = single ? 1 : 3;
	c = mbchar(string);
	a = isaletter(c) ? '=' : 0;
	vp = cp + 1;
	do
	{
		q = 0;
		n = fold;
		bp = cp;
		while ((!n || n-- > 0) && (c = mbchar(cp)))
		{
			if (a && !isaname(c))
				a = 0;
#if SHOPT_MULTIBYTE
			if (c >= 0x200)
				continue;
			if (c == '\'' || !iswprint(c))
#else
			if (c == '\'' || !isprint(c))
#endif /* SHOPT_MULTIBYTE */
			{
				q = single;
				break;
			}
			if (c == '\n')
				q = 1;
			else if (c == a)
			{
				stakwrite(bp, cp - bp);
				bp = cp;
				vp = cp + 1;
				a = 0;
			}
			else if ((c == '#' || c == '~') && cp == vp || c == ']' || c != ':' && (c = sh_lexstates[ST_NORM][c]) && c != S_EPAT)
				q = 1;
		}
		if (q & 2)
		{
			stakputc('$');
			stakputc('\'');
			cp = bp;
			n = fold - 3;
			q = 1;
			while (c = mbchar(cp))
			{
				switch (c)
				{
		    		case ('a'==97?'\033':39):
					c = 'E';
					break;
		    		case '\n':
					q = 0;
					n = fold - 1;
					break;
		    		case '\r':
					c = 'r';
					break;
		    		case '\t':
					c = 't';
					break;
		    		case '\f':
					c = 'f';
					break;
		    		case '\b':
					c = 'b';
					break;
		    		case '\a':
					c = 'a';
					break;
		    		case '\\':
					if (*cp == 'n')
					{
						c = '\n';
						q = 0;
						n = fold - 1;
						break;
					}
				case '\'':
					break;
		    		default:
#if SHOPT_MULTIBYTE
					if(!iswprint(c))
#else
					if(!isprint(c))
#endif
					{
						if ((n -= 4) <= 0)
						{
							stakwrite("'\\\n$'", 5);
							n = fold - 7;
						}
						sfprintf(staksp, "\\%03o", c);
						continue;
					}
					q = 0;
					break;
				}
				if ((n -= q + 1) <= 0)
				{
					if (!q)
					{
						stakputc('\'');
						cp = bp;
						break;
					}
					stakwrite("'\\\n$'", 5);
					n = fold - 5;
				}
				if (q)
					stakputc('\\');
				else
					q = 1;
				stakputc(c);
				bp = cp;
			}
			if (!c)
				stakputc('\'');
		}
		else if (q & 1)
		{
			stakputc('\'');
			cp = bp;
			n = fold ? (fold - 2) : 0;
			while (c = mbchar(cp))
			{
				if (c == '\n')
					n = fold - 1;
				else if (n && --n <= 0)
				{
					n = fold - 2;
					stakwrite(bp, --cp - bp);
					bp = cp;
					stakwrite("'\\\n'", 4);
				}
				else if (n == 1 && *cp == '\'')
				{
					n = fold - 5;
					stakwrite(bp, --cp - bp);
					bp = cp;
					stakwrite("'\\\n\\''", 6);
				}
				else if (c == '\'')
				{
					stakwrite(bp, cp - bp - 1);
					bp = cp;
					if (n && (n -= 4) <= 0)
					{
						n = fold - 5;
						stakwrite("'\\\n\\''", 6);
					}
					else
						stakwrite("'\\''", 4);
				}
			}
			stakwrite(bp, cp - bp - 1);
			stakputc('\'');
		}
		else if (n = fold)
		{
			cp = bp;
			while (c = mbchar(cp))
			{
				if (--n <= 0)
				{
					n = fold;
					stakwrite(bp, --cp - bp);
					bp = cp;
					stakwrite("\\\n", 2);
				}
			}
			stakwrite(bp, cp - bp - 1);
		}
		else
			stakwrite(bp, cp - bp);
		if (c)
		{
			stakputc('\\');
			stakputc('\n');
		}
	} while (c);
	stakputc(0);
	return(stakptr(offset));
}
Exemple #5
0
/*
 * print <str> quoting chars so that it can be read by the shell
 * puts null terminated result on stack, but doesn't freeze it
 */
char	*sh_fmtq(const char *string)
{
	register const char *cp = string, *op;
	register int c, state;
	int offset;
	if(!cp)
		return((char*)0);
	offset = staktell();
#if SHOPT_MULTIBYTE
	state = ((c= mbchar(cp))==0);
#else
	state = ((c= *(unsigned char*)cp++)==0);
#endif
	if(isaletter(c))
	{
#if SHOPT_MULTIBYTE
		while((c=mbchar(cp)),isaname(c));
#else
		while((c = *(unsigned char*)cp++),isaname(c));
#endif
		if(c==0)
			return((char*)string);
		if(c=='=')
		{
			if(*cp==0)
				return((char*)string);
			c = cp - string;
			stakwrite(string,c);
			string = cp;
#if SHOPT_MULTIBYTE
			c = mbchar(cp);
#else
			c = *(unsigned char*)cp++;
#endif
		}
	}
	if(c==0 || c=='#' || c=='~')
		state = 1;
#if SHOPT_MULTIBYTE
	for(;c;c= mbchar(cp))
#else
	for(;c; c= *(unsigned char*)cp++)
#endif
	{
#if SHOPT_MULTIBYTE
		if(c=='\'' || !iswprint(c))
#else
		if(c=='\'' || !isprint(c))
#endif /* SHOPT_MULTIBYTE */
			state = 2;
		else if(c==']' || (c!=':' && c<=0xff && (c=sh_lexstates[ST_NORM][c]) && c!=S_EPAT))
			state |=1;
	}
	if(state<2)
	{
		if(state==1)
			stakputc('\'');
		if(c = --cp - string)
			stakwrite(string,c);
		if(state==1)
			stakputc('\'');
	}
	else
	{
		stakwrite("$'",2);
		cp = string;
#if SHOPT_MULTIBYTE
		while(op = cp, c= mbchar(cp))
#else
		while(op = cp, c= *(unsigned char*)cp++)
#endif
		{
			state=1;
			switch(c)
			{
			    case ('a'==97?'\033':39):
				c = 'E';
				break;
			    case '\n':
				c = 'n';
				break;
			    case '\r':
				c = 'r';
				break;
			    case '\t':
				c = 't';
				break;
			    case '\f':
				c = 'f';
				break;
			    case '\b':
				c = 'b';
				break;
			    case '\a':
				c = 'a';
				break;
			    case '\\':	case '\'':
				break;
			    default:
#if SHOPT_MULTIBYTE
				if(!iswprint(c))
				{
					while(op<cp)
						sfprintf(staksp,"\\%.3o",*(unsigned char*)op++);
					continue;
				}
#else
				if(!isprint(c))
				{
					sfprintf(staksp,"\\%.3o",c);
					continue;
				}
#endif
				state=0;
				break;
			}
			if(state)
			{
				stakputc('\\');
				stakputc(c);
			}
			else
				stakwrite(op, cp-op);
		}
		stakputc('\'');
	}
	stakputc(0);
	return(stakptr(offset));
}