Beispiel #1
0
char*
fmtsignal(register int sig)
{
	char*	buf;
	int	z;

	if (sig >= 0)
	{
		if (sig <= sig_info.sigmax)
			buf = sig_info.text[sig];
		else
		{
			buf = fmtbuf(z = 20);
			sfsprintf(buf, z, "Signal %d", sig);
		}
	}
	else
	{
		sig = -sig;
		if (sig <= sig_info.sigmax)
			buf = sig_info.name[sig];
		else
		{
			buf = fmtbuf(z = 20);
			sfsprintf(buf, z, "%d", sig);
		}
	}
	return buf;
}
Beispiel #2
0
char*
fmtelapsed(register unsigned long u, register int n)
{
	register unsigned long	t;
	char*			buf;
	int			z;

	if (u == 0L)
		return "0";
	if (u == ~0L)
		return "%";
	buf = fmtbuf(z = 8);
	t = u / n;
	if (t < 60)
		sfsprintf(buf, z, "%lu.%02lus", t, (u * 100 / n) % 100);
	else if (t < 60*60)
		sfsprintf(buf, z, "%lum%02lus", t / 60, t - (t / 60) * 60);
	else if (t < 24*60*60)
		sfsprintf(buf, z, "%luh%02lum", t / (60*60), (t - (t / (60*60)) * (60*60)) / 60);
	else if (t < 7*24*60*60)
		sfsprintf(buf, z, "%lud%02luh", t / (24*60*60), (t - (t / (24*60*60)) * (24*60*60)) / (60*60));
	else if (t < 31*24*60*60)
		sfsprintf(buf, z, "%luw%02lud", t / (7*24*60*60), (t - (t / (7*24*60*60)) * (7*24*60*60)) / (24*60*60));
	else if (t < 365*24*60*60)
		sfsprintf(buf, z, "%luM%02lud", (t * 12) / (365*24*60*60), ((t * 12) - ((t * 12) / (365*24*60*60)) * (365*24*60*60)) / (12*24*60*60));
	else if (t < (365UL*4UL+1UL)*24UL*60UL*60UL)
		sfsprintf(buf, z, "%luY%02luM", t / (365*24*60*60), ((t - (t / (365*24*60*60)) * (365*24*60*60)) * 5) / (152 * 24 * 60 * 60));
	else
		sfsprintf(buf, z, "%luY%02luM", (t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL), (((t * 4) - ((t * 4) / ((365UL*4UL+1UL)*24UL*60UL*60UL)) * ((365UL*4UL+1UL)*24UL*60UL*60UL)) * 5) / ((4 * 152 + 1) * 24 * 60 * 60));
	return buf;
}
Beispiel #3
0
char*
fmttime(const char* format, time_t clock)
{
	char*	buf;
	int	z;

	buf = fmtbuf(z = 80);
	tmfmt(buf, z, format, &clock);
	return buf;
}
Beispiel #4
0
char *fmtscale(Sfulong_t n, int k) {
    Sfulong_t m;
    int r;
    int z;
    const char *u;
    char suf[3];
    char *s;
    char *buf;

    static const char scale[] = "bkMGTPE";

    u = scale;
    if (n < 1000) {
        r = 0;
    } else {
        m = 0;
        while (n >= k && *(u + 1)) {
            m = n;
            n /= k;
            u++;
        }
        if ((r = (10 * (m % k) + (k / 2)) / k) > 9) {
            r = 0;
            n++;
        }
        if (k == 1024 && n >= 1000) {
            n = 1;
            r = 0;
            u++;
        }
    }
    buf = fmtbuf(z = 8);
    s = suf;
    if (u > scale) {
        if (k == 1024) {
            *s++ = *u == 'k' ? 'K' : *u;
            *s++ = 'i';
        } else {
            *s++ = *u;
        }
    }
    *s = 0;
    if (n > 0 && n < 10) {
        char *decimal = nl_langinfo(RADIXCHAR);
        sfsprintf(buf, z, "%I*u%s%d%s", sizeof(n), n, decimal, r, suf);
    } else {
        if (r >= 5) n++;
        sfsprintf(buf, z, "%I*u%s", sizeof(n), n, suf);
    }
    return buf;
}
Beispiel #5
0
char*
fmtint(intmax_t ll, int unsign)
{
	char		*buff;
	uintmax_t	n,m;
	int		j=0,k=3*sizeof(ll);
	if(unsign || ll>=0)
		n = ll;
	else
	{
		n = -ll;
		j = 1;
	}
	if(n<10)
	{
		buff = fmtbuf(k=3);
		buff[--k] = 0;
		buff[--k] = '0' + n;
		goto skip;
	}
	buff = fmtbuf(k);
	buff[--k] = 0;
	do
	{
		k -= 3;
		if((m=n) >= 1000)
			m = n%1000;
		memcpy(buff+k,table+3*m,3);
		n /= 1000;
	}
	while(n>0);
	while(buff[k]=='0')
		k++;
skip:
	if(j)
		buff[--k] = '-';
	return(&buff[k]);
}
Beispiel #6
0
char*
fmttmx(const char* fmt, Time_t t)
{
	char*	b;
	char*	e;
	int	z;

	z = 0;
	do
	{
		b = fmtbuf(z += 80);
		e = tmxfmt(b, z, fmt, t);
	} while (e == b + z);
	return b;
}
Beispiel #7
0
char*
fmtident(const char* a)
{
	register char*	s = (char*)a;
	register char*	t;
	char*		buf;
	int		i;

	i = 0;
	for (;;)
	{
		while (isspace(*s))
			s++;
		if (s[0] == '[')
		{
			while (*++s && *s != '\n');
			i |= USAGE;
		}
		else if (s[0] == '@' && s[1] == '(' && s[2] == '#' && s[3] == ')')
			s += 4;
		else if (s[0] == '$' && s[1] == 'I' && s[2] == 'd' && s[3] == ':' && isspace(s[4]))
		{
			s += 5;
			i |= IDENT;
		}
		else
			break;
	}
	if (i)
	{
		i &= IDENT;
		for (t = s; isprint(*t) && *t != '\n'; t++)
			if (i && t[0] == ' ' && t[1] == '$')
				break;
		while (t > s && isspace(t[-1]))
			t--;
		i = t - s;
		buf = fmtbuf(i + 1);
		memcpy(buf, s, i);
		s = buf;
		s[i] = 0;
	}
	return s;
}
Beispiel #8
0
char*
fmtfs(struct stat* st)
{
	register Id_t*		ip;
	register void*		mp;
	register Mnt_t*		mnt;
	register char*		s;
	struct stat		rt;
	char*			buf;

	static Dt_t*		dict;
	static Dtdisc_t		disc;

	if (!dict)
	{
		disc.key = offsetof(Id_t, id);
		disc.size = sizeof(dev_t);
		dict = dtopen(&disc, Dthash);
	}
	else if (ip = (Id_t*)dtmatch(dict, &st->st_dev))
		return ip->name;
	s = FS_default;
	if (mp = mntopen(NiL, "r"))
	{
		while ((mnt = mntread(mp)) && (stat(mnt->dir, &rt) || rt.st_dev != st->st_dev));
		if (mnt && mnt->type)
			s = mnt->type;
	}
	if (!dict || !(ip = newof(0, Id_t, 1, strlen(s))))
	{
		if (!mp)
			return s;
		buf = fmtbuf(strlen(s) + 1);
		strcpy(buf, s);
		mntclose(mp);
		return buf;
	}
	strcpy(ip->name, s);
	if (mp)
		mntclose(mp);
	dtinsert(dict, ip);
	return ip->name;
}
Beispiel #9
0
int
b_mktemp(int argc, char** argv, Shbltin_t* context)
{
	mode_t		mode = 0;
	mode_t		mask;
	int		fd;
	int		i;
	int		quiet = 0;
	int		unsafe = 0;
	int*		fdp = &fd;
	char*		dir = "";
	char*		pfx;
	char*		t;
	char		path[PATH_MAX];

	cmdinit(argc, argv, context, ERROR_CATALOG, ERROR_NOTIFY);
	for (;;)
	{
		switch (optget(argv, usage))
		{
		case 'd':
			fdp = 0;
			continue;
		case 'm':
			mode = strperm(pfx = opt_info.arg, &opt_info.arg, S_IRWXU);
			if (*opt_info.arg)
				error(ERROR_exit(0), "%s: invalid mode", pfx);
			continue;
		case 'p':
			if ((t = getenv("TMPDIR")) && *t)
				dir = 0;
			else
				dir = opt_info.arg;
			continue;
		case 'q':
			quiet = 1;
			continue;
		case 't':
			dir = 0;
			continue;
		case 'u':
			unsafe = 1;
			fdp = 0;
			continue;
		case 'R':
			if (!pathtemp(NiL, 0, opt_info.arg, "/seed", NiL))
				error(2, "%s: regression test initializtion failed", opt_info.arg);
			continue;
		case ':':
			error(2, "%s", opt_info.arg);
			break;
		case '?':
			error(ERROR_usage(2), "%s", opt_info.arg);
			break;
		}
		break;
	}
	argv += opt_info.index;
	if (error_info.errors || (pfx = *argv++) && *argv)
		error(ERROR_usage(2), "%s", optusage(NiL));
	mask = umask(0);
	if (!mode)
		mode = (fdp ? (S_IRUSR|S_IWUSR) : S_IRWXU) & ~mask;
	umask(~mode & (S_IRWXU|S_IRWXG|S_IRWXO));
	if (!pfx)
	{
		pfx = "tmp_";
		if (dir && !*dir)
			dir = 0;
	}
	if (t = strrchr(pfx, '/'))
	{
		i = ++t - pfx;
		dir = fmtbuf(i);
		memcpy(dir, pfx, i);
		dir[i] = 0;
		pfx = t;
	}
	for (;;)
	{
		if (!pathtemp(path, sizeof(path), dir, pfx, fdp))
		{
			if (quiet)
				error_info.errors++;
			else
				error(ERROR_SYSTEM|2, "cannot create temporary path");
			break;
		}
		if (fdp || unsafe || !mkdir(path, mode))
		{
			if (fdp)
				close(*fdp);
			sfputr(sfstdout, path, '\n');
			break;
		}
		if (sh_checksig(context))
		{
			error_info.errors++;
			break;
		}
	}
	umask(mask);
	return error_info.errors != 0;
}
Beispiel #10
0
char*
fmtrec(Recfmt_t f, int fs)
{
	char*	b;
	char*	e;
	char*	s;
	long	n;
	char	del[2];

	b = s = fmtbuf(n = 32);
	e = b + n;
	switch (RECTYPE(f))
	{
	case REC_delimited:
		*s++ = 'd';
		if ((del[0] = REC_D_DELIMITER(f)) != '\n')
		{
			del[1] = 0;
			if (fs)
				sfsprintf(s, e - s, "0x%02x", *(unsigned char*)del);
			else
				sfsprintf(s, e - s, "%s", fmtquote(del, NiL, NiL, 1, 0));
		}
		else
			*s = 0;
		break;
	case REC_fixed:
		if (!fs)
			*s++ = 'f';
		sfsprintf(s, e - s, "%lu", REC_F_SIZE(f));
		break;
	case REC_variable:
		*s++ = 'v';
		if (n = REC_V_SIZE(f))
			s += sfsprintf(s, e - s, "%lu", n);
		if (REC_V_HEADER(f) != 4)
			s += sfsprintf(s, e - s, "h%u", REC_V_HEADER(f));
		if (REC_V_OFFSET(f) != 0)
			s += sfsprintf(s, e - s, "o%u", REC_V_OFFSET(f));
		if (REC_V_LENGTH(f) != 2)
			s += sfsprintf(s, e - s, "z%u", REC_V_LENGTH(f));
		if (REC_V_LITTLE(f) != 0)
			*s++ = 'l';
		if (REC_V_INCLUSIVE(f) == 0)
			*s++ = 'n';
		*s = 0;
		break;
	case REC_method:
		*s++ = 'm';
		switch (n = REC_M_INDEX(f))
		{
		case REC_M_data:
			sfsprintf(s, e - s, "data");
			break;
		case REC_M_path:
			sfsprintf(s, e - s, "path");
			break;
		default:
			sfsprintf(s, e - s, "%lu", n);
			break;
		}
		break;
	case REC_none:
		*s++ = 'n';
		*s = 0;
		break;
	default:
		sfsprintf(s, e - s, "u%u.0x%07x", RECTYPE(f), REC_U_ATTRIBUTES(f));
		break;
	}
	return b;
}
Beispiel #11
0
char*
fmtre(const char* as)
{
	register char*		s = (char*)as;
	register int		c;
	register char*		t;
	register Stack_t*	p;
	char*			x;
	int			n;
	int			end;
	char*			buf;
	Stack_t			stack[32];

	end = 1;
	c = 2 * strlen(s) + 1;
	t = buf = fmtbuf(c);
	p = stack;
	if (*s != '*' || *(s + 1) == '(' || *(s + 1) == '-' && *(s + 2) == '(')
		*t++ = '^';
	else
		s++;
	for (;;)
	{
		switch (c = *s++)
		{
		case 0:
			break;
		case '\\':
			if (!(c = *s++) || c == '{' || c == '}')
				return 0;
			*t++ = '\\';
			if ((*t++ = c) == '(' && *s == '|')
			{
				*t++ = *s++;
				goto logical;
			}
			continue;
		case '[':
			*t++ = c;
			n = 0;
			if ((c = *s++) == '!')
			{
				*t++ = '^';
				c = *s++;
			}
			else if (c == '^')
			{
				if ((c = *s++) == ']')
				{
					*(t - 1) = '\\';
					*t++ = '^';
					continue;
				}
				n = '^';
			}
			for (;;)
			{
				if (!(*t++ = c))
					return 0;
				if ((c = *s++) == ']')
				{
					if (n)
						*t++ = n;
					*t++ = c;
					break;
				}
			}
			continue;
		case '{':
			for (x = s; *x && *x != '}'; x++);
			if (*x++ && (*x == '(' || *x == '-' && *(x + 1) == '('))
			{
				if (p >= &stack[elementsof(stack)])
					return 0;
				p->beg = s - 1;
				s = x;
				p->len = s - p->beg;
				if (p->min = *s == '-')
					s++;
				p++;
				*t++ = *s++;
			}
			else
				*t++ = c;
			continue;
		case '*':
			if (!*s)
			{
				end = 0;
				break;
			}
			/*FALLTHROUGH*/
		case '?':
		case '+':
		case '@':
		case '!':
		case '~':
			if (*s == '(' || c != '~' && *s == '-' && *(s + 1) == '(')
			{
				if (p >= &stack[elementsof(stack)])
					return 0;
				p->beg = s - 1;
				if (c == '~')
				{
					if (*(s + 1) == 'E' && *(s + 2) == ')')
					{
						for (s += 3; *t = *s; t++, s++);
						continue;
					}
					p->len = 0;
					p->min = 0;
					*t++ = *s++;
					*t++ = '?';
				}
				else
				{
					p->len = c != '@';
					if (p->min = *s == '-')
						s++;
					*t++ = *s++;
				}
				p++;
			}
			else
			{
				switch (c)
				{
				case '*':
					*t++ = '.';
					break;
				case '?':
					c = '.';
					break;
				case '+':
				case '!':
					*t++ = '\\';
					break;
				}
				*t++ = c;
			}
			continue;
		case '(':
			if (p >= &stack[elementsof(stack)])
				return 0;
			p->beg = s - 1;
			p->len = 0;
			p->min = 0;
			p++;
			*t++ = c;
			continue;
		case ')':
			if (p == stack)
				return 0;
			*t++ = c;
			p--;
			for (c = 0; c < p->len; c++)
				*t++ = p->beg[c];
			if (p->min)
				*t++ = '?';
			continue;
		case '^':
		case '.':
		case '$':
			*t++ = '\\';
			*t++ = c;
			continue;
		case '|':
			if (t == buf || *(t - 1) == '(')
				return 0;
		logical:
			if (!*s || *s == ')')
				return 0;
			/*FALLTHROUGH*/
		default:
			*t++ = c;
			continue;
		}
		break;
	}
	if (p != stack)
		return 0;
	if (end)
		*t++ = '$';
	*t = 0;
	return buf;
}
Beispiel #12
0
char*
_ast_strerror(int err)
{
	char*		msg;
	int		z;

#if _lib_strerror
	z = errno;
	msg = strerror(err);
	errno = z;
#else
	if (err > 0 && err <= sys_nerr)
		msg = (char*)sys_errlist[err];
	else
		msg = 0;
#endif
	if (msg)
	{
#if !_PACKAGE_astsa
		if (ERROR_translating())
		{
#if _lib_strerror
			static int	sys;

			if (!sys)
			{
				char*	s;
				char*	t;
				char*	p;

#if _lib_strerror
				/*
				 * stash the pending strerror() msg
				 */

				msg = strcpy(fmtbuf(strlen(msg) + 1), msg);
#endif

				/*
				 * make sure that strerror() translates
				 */

				if (!(s = strerror(1)))
					sys = -1;
				else
				{
					t = fmtbuf(z = strlen(s) + 1);
					strcpy(t, s);
					ast.locale.set |= AST_LC_internal;
					p = setlocale(LC_MESSAGES, NiL);
					setlocale(LC_MESSAGES, "C");
					sys = (s = strerror(1)) && strcmp(s, t) ? 1 : -1;
					setlocale(LC_MESSAGES, p);
					ast.locale.set &= ~AST_LC_internal;
				}
			}
			if (sys > 0)
				return msg;
#endif
			return ERROR_translate(NiL, NiL, "errlist", msg);
		}
#endif
		return msg;
	}
	msg = fmtbuf(z = 32);
	sfsprintf(msg, z, ERROR_translate(NiL, NiL, "errlist", "Error %d"), err);
	return msg;
}
Beispiel #13
0
char*
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
{
	register unsigned char*	s = (unsigned char*)as;
	register unsigned char*	e = s + n;
	register char*		b;
	register int		c;
	register int		m;
	register int		escaped;
	register int		spaced;
	register int		doublequote;
	register int		singlequote;
	int			shell;
	char*			f;
	char*			buf;

	c = 4 * (n + 1);
	if (qb)
		c += strlen((char*)qb);
	if (qe)
		c += strlen((char*)qe);
	b = buf = fmtbuf(c);
	shell = 0;
	doublequote = 0;
	singlequote = 0;
	if (qb)
	{
		if (qb[0] == '$' && qb[1] == '\'' && qb[2] == 0)
			shell = 1;
		else if ((flags & FMT_SHELL) && qb[1] == 0)
		{
			if (qb[0] == '"')
				doublequote = 1;
			else if (qb[0] == '\'')
				singlequote = 1;
		}
		while (*b = *qb++)
			b++;
	}
	else if (flags & FMT_SHELL)
		doublequote = 1;
	f = b;
	escaped = spaced = !!(flags & FMT_ALWAYS);
	while (s < e)
	{
		if ((m = mbsize(s)) > 1 && (s + m) <= e)
		{
#if _hdr_wchar && _hdr_wctype
			c = mbchar(s);
			if (!spaced && !escaped && (iswspace(c) || iswcntrl(c)))
				spaced = 1;
			s -= m;
#endif
			while (m--)
				*b++ = *s++;
		}
		else
		{
			c = *s++;
			if (!(flags & FMT_ESCAPED) && (iscntrl(c) || !isprint(c) || c == '\\'))
			{
				escaped = 1;
				*b++ = '\\';
				switch (c)
				{
				case CC_bel:
					c = 'a';
					break;
				case '\b':
					c = 'b';
					break;
				case '\f':
					c = 'f';
					break;
				case '\n':
					c = 'n';
					break;
				case '\r':
					c = 'r';
					break;
				case '\t':
					c = 't';
					break;
				case CC_vt:
					c = 'v';
					break;
				case CC_esc:
					c = 'E';
					break;
				case '\\':
					break;
				default:
					if (!(flags & FMT_WIDE) || !(c & 0200))
					{
						*b++ = '0' + ((c >> 6) & 07);
						*b++ = '0' + ((c >> 3) & 07);
						c = '0' + (c & 07);
					}
					else
						b--;
					break;
				}
			}
Beispiel #14
0
static int
prformat(Sfio_t* sp, void* vp, Sffmt_t* dp)
{
	register Fmt_t*		fmt = (Fmt_t*)dp;
	register Exnode_t*	node;
	register char*		s;
	register char*		txt;
	int			n;
	int			from;
	int			to;
	time_t			tm;

	dp->flags |= SFFMT_VALUE;
	if (fmt->args)
	{
		if (node = (dp->fmt == '*') ? fmt->args->param[dp->size] : fmt->args->arg)
			fmt->value = exeval(fmt->expr, node, fmt->env);
		else
			fmt->value.integer = 0;
		to = fmt->args->arg->type;
	}
	else if (!(fmt->actuals = fmt->actuals->data.operand.right))
		exerror("printf: not enough arguments");
	else
	{
		node = fmt->actuals->data.operand.left;
		from = node->type;
		switch (dp->fmt)
		{
		case 'f':
		case 'g':
			to = FLOATING;
			break;
		case 's':
		case '[':
			to = STRING;
			break;
		default:
			switch (from)
			{
			case INTEGER:
			case UNSIGNED:
				to = from;
				break;
			default:
				to = INTEGER;
				break;
			}
			break;
		}
		if (to == from)
			fmt->value = exeval(fmt->expr, node, fmt->env);
		else
		{
			node = excast(fmt->expr, node, to, NiL, 0);
			fmt->value = exeval(fmt->expr, node, fmt->env);
			node->data.operand.left = 0;
			exfree(fmt->expr, node);
			if (to == STRING)
			{
				if (fmt->value.string)
				{
					n = strlen(fmt->value.string);
					if (s = fmtbuf(n + 1))
						memcpy(s, fmt->value.string, n + 1);
					vmfree(fmt->expr->vm, fmt->value.string);
					fmt->value.string = s;
				}
				if (!fmt->value.string)
					fmt->value.string = "";
			}
		}
	}
	switch (to)
	{
	case STRING:
		*((char**)vp) = fmt->value.string;
		fmt->fmt.size = -1;
		break;
	case FLOATING:
		*((double*)vp) = fmt->value.floating;
		fmt->fmt.size = sizeof(double);
		break;
	default:
		*((Sflong_t*)vp) = fmt->value.integer;
		dp->size = sizeof(Sflong_t);
		break;
	}
	if (dp->n_str > 0)
	{
		if (!fmt->tmp && !(fmt->tmp = sfstropen()))
			txt = exnospace();
		else
		{
			sfprintf(fmt->tmp, "%.*s", dp->n_str, dp->t_str);
			txt = exstash(fmt->tmp, NiL);
		}
	}
	else
		txt = 0;
	switch (dp->fmt)
	{
	case 'q':
	case 'Q':
		s = *((char**)vp);
		*((char**)vp) = fmtquote(s, "$'", "'", strlen(s), 0);
		dp->fmt = 's';
		dp->size = -1;
		break;
	case 'S':
		dp->flags &= ~SFFMT_LONG;
		s = *((char**)vp);
		if (txt)
		{
			if (streq(txt, "identifier"))
			{
				if (*s && !isalpha(*s))
					*s++ = '_';
				for (; *s; s++)
					if (!isalnum(*s))
						*s = '_';
			}
			else if (streq(txt, "invert"))
			{
				for (; *s; s++)
					if (isupper(*s))
						*s = tolower(*s);
					else if (islower(*s))
						*s = toupper(*s);
			}
			else if (streq(txt, "lower"))
			{
				for (; *s; s++)
					if (isupper(*s))
						*s = tolower(*s);
			}
			else if (streq(txt, "upper"))
			{
				for (; *s; s++)
					if (islower(*s))
						*s = toupper(*s);
			}
			else if (streq(txt, "variable"))
			{
				for (; *s; s++)
					if (!isalnum(*s) && *s != '_')
						*s = '.';
			}
		}
		dp->fmt = 's';
		dp->size = -1;
		break;
	case 't':
	case 'T':
		if ((tm = *((Sflong_t*)vp)) == -1)
			tm = time(NiL);
		*((char**)vp) = fmttime(txt ? txt : "%?%K", tm);
		dp->fmt = 's';
		dp->size = -1;
		break;
	}
	return 0;
}
Beispiel #15
0
char*
fmtfmt(const char* as)
{
	register char*	s = (char*)as;
	char*		buf;
	int		i;
	int		c;
	int		a;
	int		q;
	int		x;
	int		t;
	int		m;
	int		n;
	int		z;
	char		formats[256];
	unsigned int	extra[elementsof(formats)];

	z = 1;
	i = m = 0;
	for (;;)
	{
		switch (*s++)
		{
		case 0:
			break;
		case '%':
			if (*s == '%')
				continue;
			n = 0;
			a = 0;
			q = 0;
			t = '?';
			x = 0;
			for (;;)
			{
				switch (c = *s++)
				{
				case 0:
					s--;
					break;
				case '(':
					q++;
					continue;
				case ')':
					if (--q <= 0)
						n = 0;
					continue;
				case '0': case '1': case '2': case '3':
				case '4': case '5': case '6': case '7':
				case '8': case '9':
					n = n * 10 + (c - '0');
					continue;
				case '$':
					a = n;
					n = 0;
					continue;
				case '*':
					x++;
					n = 0;
					continue;
				case 'h':
					if (!q)
						t = t == 'h' ? 'c' : 'h';
					continue;
				case 'l':
					if (!q)
						t = t == 'l' ? 'j' : 'l';
					continue;
				case 'j':
				case 't':
				case 'z':
					if (!q)
						t = c;
					continue;
				case 'c':
				case 'p':
				case 's':
					if (!q)
					{
						t = c;
						break;
					}
					continue;
				case 'e':
				case 'g':
					if (!q)
					{
						switch (t)
						{
						case 'j':
							t = 'D';
							break;
						default:
							t = 'd';
							break;
						}
						break;
					}
					continue;
				case 'f':
					if (!q)
					{
						switch (t)
						{
						case 'j':
							t = 'D';
							break;
						case 'l':
							t = 'd';
							break;
						default:
							t = c;
							break;
						}
						break;
					}
					continue;
				default:
					if (!q && isalpha(c))
					{
						if (t == '?')
							t = 'i';
						break;
					}
					n = 0;
					continue;
				}
				break;
			}
			if (a)
				i = a;
			else
				i++;
			if (i < elementsof(formats))
			{
				formats[i] = t;
				if (extra[i] = x)
					do z++; while (x /= 10);
				if (m < i)
					m = i;
			}
			continue;
		default:
			continue;
		}
		break;
	}
	s = buf = fmtbuf(m + z);
	for (i = 1; i <= m; i++)
	{
		if (extra[i])
			s += sfsprintf(s, 10, "%d", extra[m]);
		*s++ = formats[i];
	}
	*s = 0;
	return buf;
}
Beispiel #16
0
char*
fmtquote(const char* as, const char* qb, const char* qe, size_t n, int flags)
{
	register unsigned char*	s = (unsigned char*)as;
	register unsigned char*	e = s + n;
	register char*		b;
	register int		c;
	int			k;
	int			q = 0;
	char*			buf;

	c = 4 * (n + 1);
	if (qb)
	{
		k = strlen((char*)qb);
		c += k;
	}
	else
	{
		k = 0;
		if (qe)
			c += strlen((char*)qe);
	}
	b = buf = fmtbuf(c);
	if (qb)
	{
		q = qb[0] == '$' && qb[1] == '\'' && qb[2] == 0 ? 1 : 0;
		while ((*b = *qb++))
			b++;
		k = (flags & 1) ? 0 : (b - buf);
	}
	while (s < e)
	{
		c = *s++;
		if (iscntrl(c) || !isprint(c) || c == '\\')
		{
			k = 0;
			*b++ = '\\';
			switch (c)
			{
			case CC_bel:
				c = 'a';
				break;
			case '\b':
				c = 'b';
				break;
			case '\f':
				c = 'f';
				break;
			case '\n':
				c = 'n';
				break;
			case '\r':
				c = 'r';
				break;
			case '\t':
				c = 't';
				break;
			case CC_vt:
				c = 'v';
				break;
			case CC_esc:
				c = 'E';
				break;
			case '\\':
				break;
			default:
				if (!(flags & 2) || !(c & 0200))
				{
					*b++ = '0' + ((c >> 6) & 07);
					*b++ = '0' + ((c >> 3) & 07);
					c = '0' + (c & 07);
				}
				else
					b--;
				break;
			}