Exemplo n.º 1
0
int
strexp(register char* s, int flags)
{
	register char*		t;
	register int		c;
	char*			b;
	char*			e;
	int			w;
	Mbstate_t		q;

	b = t = s;
	while (c = *s++)
	{
		if (c == '\\')
		{
			c = chrexp(s - 1, &e, &w, flags);
			s = e;
			if (c < 0)
				continue;
			if (w)
			{
				mbinit(&q);
				t += mbconv(t, c, &q);
				continue;
			}
		}
		*t++ = c;
	}
	*t = 0;
	return t - b;
}
Exemplo n.º 2
0
int
chrexp(register const char* s, char** p, int* m, register int flags)
{
	register const char*	q;
	register int		c;
	const char*		e;
	const char*		b;
	char*			r;
	int			n;
	int			w;

	w = 0;
	for (;;)
	{
		b = s;
		switch (c = mbchar(s))
		{
		case 0:
			s--;
			break;
		case '\\':
			switch (c = *s++)
			{
			case '0': case '1': case '2': case '3':
			case '4': case '5': case '6': case '7':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c -= '0';
				q = s + 2;
				while (s < q)
					switch (*s)
					{
					case '0': case '1': case '2': case '3':
					case '4': case '5': case '6': case '7':
						c = (c << 3) + *s++ - '0';
						break;
					default:
						q = s;
						break;
					}
				break;
			case 'a':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = CC_bel;
				break;
			case 'b':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = '\b';
				break;
			case 'c': /*DEPRECATED*/
			case 'C':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				if (c = *s)
				{
					s++;
					if (c == '\\')
					{
						c = chrexp(s - 1, &r, 0, flags);
						s = (const char*)r;
					}
					if (islower(c))
						c = toupper(c);
					c = ccmapc(c, CC_NATIVE, CC_ASCII);
					c ^= 0x40;
					c = ccmapc(c, CC_ASCII, CC_NATIVE);
				}
				break;
			case 'e': /*DEPRECATED*/
			case 'E':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = CC_esc;
				break;
			case 'f':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = '\f';
				break;
			case 'M':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				if (*s == '-')
				{
					s++;
					c = CC_esc;
				}
				break;
			case 'n':
				if (flags & FMT_EXP_NONL)
					continue;
				if (!(flags & FMT_EXP_LINE))
					goto noexpand;
				c = '\n';
				break;
			case 'r':
				if (flags & FMT_EXP_NOCR)
					continue;
				if (!(flags & FMT_EXP_LINE))
					goto noexpand;
				c = '\r';
				break;
			case 't':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = '\t';
				break;
			case 'v':
				if (!(flags & FMT_EXP_CHAR))
					goto noexpand;
				c = CC_vt;
				break;
			case 'u':
			case 'U':
			case 'x':
				if (q = c == 'u' ? (s + 4) : c == 'U' ? (s + 8) : (char*)0)
				{
					if (!(flags & FMT_EXP_WIDE))
						goto noexpand;
					w = 1;
				}
				b = e = s;
				n = 0;
				c = 0;
				while (!e || !q || s < q)
				{
					switch (*s)
					{
					case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
						c = (c << 4) + *s++ - 'a' + 10;
						n++;
						continue;
					case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
						c = (c << 4) + *s++ - 'A' + 10;
						n++;
						continue;
					case '0': case '1': case '2': case '3': case '4':
					case '5': case '6': case '7': case '8': case '9':
						c = (c << 4) + *s++ - '0';
						n++;
						continue;
					case '{':
					case '[':
						if (s != e)
							break;
						e = 0;
						s++;
						continue;
					case '}':
					case ']':
						if (!e)
							s++;
						break;
					default:
						break;
					}
					break;
				}
				if (n <= 2 && !(flags & FMT_EXP_CHAR) || n > 2 && (w = 1) && !(flags & FMT_EXP_WIDE))
				{
					c = '\\';
					s = b;
				}
				break;
			case 0:
				s--;
				break;
			}
			break;
		default:
			if ((s - b) > 1)
				w = 1;
			break;
		}
		break;
	}
 normal:
	if (p)
		*p = (char*)s;
	if (m)
		*m = w;
	return c;
 noexpand:
	c = '\\';
	s--;
	goto normal;
}
Exemplo n.º 3
0
int
chresc(register const char* s, char** p)
{
	return chrexp(s, p, NiL, FMT_EXP_CHAR|FMT_EXP_LINE|FMT_EXP_WIDE);
}
Exemplo n.º 4
0
Arquivo: chresc.c Projeto: att/ast
int chrexp(const char *s, char **p, int *m, int flags) {
    const char *t;
    int c;
    const char *e;
    const char *b;
    char *r;
    int n;
    int x;
    wchar_t d;
    Mbstate_t q;
    bool u;
    bool w;

    u = w = 0;
    mbinit(&q);
    for (;;) {
        b = s;
        c = mbchar(&d, (char **)&s, MB_LEN_MAX, &q);
        switch (c) {
            case 0:
                s = b;
                break;
            case '\\':
                b = s;
                switch (c = *s++) {
                    case '0':
                    case '1':
                    case '2':
                    case '3':
                    case '4':
                    case '5':
                    case '6':
                    case '7':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c -= '0';
                        t = s + 2;
                        while (s < t) {
                            switch (*s) {
                                case '0':
                                case '1':
                                case '2':
                                case '3':
                                case '4':
                                case '5':
                                case '6':
                                case '7':
                                    c = (c << 3) + *s++ - '0';
                                    break;
                                default:
                                    t = s;
                                    break;
                            }
                        }
                        break;
                    case 'a':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = CC_bel;
                        break;
                    case 'b':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = '\b';
                        break;
                    case 'c': /*DEPRECATED*/
                    case 'C':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = *s;
                        if (c) {
                            s++;
                            if (c == '\\') {
                                c = chrexp(s - 1, &r, 0, flags);
                                s = (const char *)r;
                            }
                            if (islower(c)) c = toupper(c);
                            c ^= 0x40;
                        }
                        break;
                    case 'e': /*DEPRECATED*/
                    case 'E':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = CC_esc;
                        break;
                    case 'f':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = '\f';
                        break;
                    case 'M':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        if (*s == '-') {
                            s++;
                            c = CC_esc;
                        }
                        break;
                    case 'n':
                        if (flags & FMT_EXP_NONL) continue;
                        if (!(flags & FMT_EXP_LINE)) goto noexpand;
                        c = '\n';
                        break;
                    case 'r':
                        if (flags & FMT_EXP_NOCR) continue;
                        if (!(flags & FMT_EXP_LINE)) goto noexpand;
                        c = '\r';
                        break;
                    case 't':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = '\t';
                        break;
                    case 'v':
                        if (!(flags & FMT_EXP_CHAR)) goto noexpand;
                        c = CC_vt;
                        break;
                    case 'u':
                        u = 1;
                    // FALLTHRU
                    case 'w':
                        t = s + 4;
                        goto wex;
                    case 'U':
                        u = 1;
                    // FALLTHRU
                    case 'W':
                        t = s + 8;
                    wex:
                        if (!(flags & FMT_EXP_WIDE)) goto noexpand;
                        w = 1;
                        goto hex;
                    case 'x':
                        t = s + 2;
                    hex:
                        e = s;
                        n = 0;
                        c = 0;
                        x = 0;
                        while (!e || !t || s < t) {
                            switch (*s) {
                                case 'a':
                                case 'b':
                                case 'c':
                                case 'd':
                                case 'e':
                                case 'f':
                                    c = (c << 4) + *s++ - 'a' + 10;
                                    n++;
                                    continue;
                                case 'A':
                                case 'B':
                                case 'C':
                                case 'D':
                                case 'E':
                                case 'F':
                                    c = (c << 4) + *s++ - 'A' + 10;
                                    n++;
                                    continue;
                                case '0':
                                case '1':
                                case '2':
                                case '3':
                                case '4':
                                case '5':
                                case '6':
                                case '7':
                                case '8':
                                case '9':
                                    c = (c << 4) + *s++ - '0';
                                    n++;
                                    continue;
                                case '{':
                                case '[':
                                    if (s != e) break;
                                    e = 0;
                                    s++;
                                    if (w && (*s == 'U' || *s == 'W') && *(s + 1) == '+') s += 2;
                                    continue;
                                case '-':
                                    if (e) break;
                                    if (*(s + 1) != '}' && *(s + 1) != ']') {
                                        if (!*(s + 1) || (*(s + 2) != '}' && *(s + 2) != ']')) {
                                            break;
                                        }
                                        x = *(unsigned char *)(s + 1);
                                        s += 2;
                                    } else {
                                        x = -1;
                                        s++;
                                    }
                                    /*FALLTHROUGH*/
                                case '}':
                                case ']':
                                    if (!e) e = ++s;
                                    break;
                                default:
                                    break;
                            }
                            break;
                        }
                        if (e) {
                            if (n < 8 || (n == 8 && c >= 0)) {
                                if (!w) {
                                    if (n > 2) {
                                        if (!(flags & FMT_EXP_WIDE)) goto noexpand;
                                        w = 1;
                                    } else if (!(flags & FMT_EXP_CHAR)) {
                                        goto noexpand;
                                    } else {
                                        break;
                                    }
                                }
                                if (!mbwide()) w = 0;
                                if (c <= 0x7f) break;
                                if (u) {
                                    uint32_t i = c;
                                    wchar_t o;

                                    if (!utf32invalid(i) && utf32stowcs(&o, &i, 1) > 0) {
                                        c = o;
                                        break;
                                    }
                                } else if (w || c <= ast.byte_max) {
                                    break;
                                }
                            }
                            if (x) {
                                c = x;
                                w = 0;
                                break;
                            }
                        }
                        /*FALLTHROUGH*/
                    case 0:
                        goto noexpand;
                }
                break;
            default:
                if ((s - b) > 1) w = 1;
                break;
            noexpand:
                s = b;
                w = 0;
                c = '\\';
                break;
        }
        break;
    }
    if (m) *m = w;
    if (p) *p = (char *)s;
    return c;
}
Exemplo n.º 5
0
Arquivo: chresc.c Projeto: att/ast
int chresc(const char *s, char **p) {
    return chrexp(s, p, NULL, FMT_EXP_CHAR | FMT_EXP_LINE | FMT_EXP_WIDE);
}