Пример #1
0
/* get variable string value */
char *
str_val(struct tbl *vp)
{
	char *s;

	if ((vp->flag&SPECIAL))
		getspec(vp);
	if (!(vp->flag&ISSET))
		s = null;		/* special to dollar() */
	else if (!(vp->flag&INTEGER))	/* string source */
		s = vp->val.s + vp->type;
	else {				/* integer source */
		/* worst case number length is when base=2, so use BITS(long) */
		/* minus base #     number    null */
		char strbuf[1 + 2 + 1 + BITS(long) + 1];
		const char *digits = (vp->flag & UCASEV_AL) ?
		    "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" :
		    "0123456789abcdefghijklmnopqrstuvwxyz";
		unsigned long n;
		int base;

		s = strbuf + sizeof(strbuf);
		if (vp->flag & INT_U)
			n = (unsigned long) vp->val.i;
		else
			n = (vp->val.i < 0) ? -vp->val.i : vp->val.i;
		base = (vp->type == 0) ? 10 : vp->type;
		if (base < 2 || base > strlen(digits))
			base = 10;

		*--s = '\0';
		do {
			*--s = digits[n % base];
			n /= base;
		} while (n != 0);
		if (base != 10) {
			*--s = '#';
			*--s = digits[base % 10];
			if (base >= 10)
				*--s = digits[base / 10];
		}
		if (!(vp->flag & INT_U) && vp->val.i < 0)
			*--s = '-';
		if (vp->flag & (RJUST|LJUST)) /* case already dealt with */
			s = formatstr(vp, s);
		else
			s = str_save(s, ATEMP);
	}
	return s;
}
Пример #2
0
tableput()
{
saveline();
savefill();
ifdivert();
cleanfc();
getcomm();
getspec();
gettbl();
getstop();
checkuse();
choochar();
maktab();
runout();
release();
rstofill();
endoff();
restline();
}
Пример #3
0
static int
getint(struct tbl *vp, mksh_ari_u *nump, bool arith)
{
	mksh_uari_t c, num = 0, base = 10;
	const char *s;
	bool have_base = false, neg = false;

	if (vp->flag & SPECIAL)
		getspec(vp);
	/* XXX is it possible for ISSET to be set and val.s to be NULL? */
	if (!(vp->flag & ISSET) || (!(vp->flag & INTEGER) && vp->val.s == NULL))
		return (-1);
	if (vp->flag & INTEGER) {
		nump->i = vp->val.i;
		return (vp->type);
	}
	s = vp->val.s + vp->type;

	do {
		c = (unsigned char)*s++;
	} while (ksh_isspace(c));

	switch (c) {
	case '-':
		neg = true;
		/* FALLTHROUGH */
	case '+':
		c = (unsigned char)*s++;
		break;
	}

	if (c == '0' && arith) {
		if (ksh_eq(s[0], 'X', 'x')) {
			/* interpret as hexadecimal */
			base = 16;
			++s;
			goto getint_c_style_base;
		} else if (Flag(FPOSIX) && ksh_isdigit(s[0]) &&
		    !(vp->flag & ZEROFIL)) {
			/* interpret as octal (deprecated) */
			base = 8;
 getint_c_style_base:
			have_base = true;
			c = (unsigned char)*s++;
		}
	}

	do {
		if (c == '#') {
			/* ksh-style base determination */
			if (have_base || num < 1)
				return (-1);
			if ((base = num) == 1) {
				/* mksh-specific extension */
				unsigned int wc;

				if (!UTFMODE)
					wc = *(const unsigned char *)s;
				else if (utf_mbtowc(&wc, s) == (size_t)-1)
					/* OPTU-8 -> OPTU-16 */
					/*
					 * (with a twist: 1#\uEF80 converts
					 * the same as 1#\x80 does, thus is
					 * not round-tripping correctly XXX)
					 */
					wc = 0xEF00 + *(const unsigned char *)s;
				nump->u = (mksh_uari_t)wc;
				return (1);
			} else if (base > 36)
				base = 10;
			num = 0;
			have_base = true;
			continue;
		}
		if (ksh_isdigit(c))
			c = ksh_numdig(c);
		else if (ksh_isupper(c))
			c = ksh_numuc(c) + 10;
		else if (ksh_islower(c))
			c = ksh_numlc(c) + 10;
		else
			return (-1);
		if (c >= base)
			return (-1);
		/* handle overflow as truncation */
		num = num * base + c;
	} while ((c = (unsigned char)*s++));

	if (neg)
		num = -num;
	nump->u = num;
	return (base);
}
Пример #4
0
/* get variable string value */
char *
str_val(struct tbl *vp)
{
	char *s;

	if ((vp->flag&SPECIAL))
		getspec(vp);
	if (!(vp->flag&ISSET))
		/* special to dollar() */
		s = null;
	else if (!(vp->flag&INTEGER))
		/* string source */
		s = vp->val.s + vp->type;
	else {
		/* integer source */
		mksh_uari_t n;
		unsigned int base;
		/**
		 * worst case number length is when base == 2:
		 *	1 (minus) + 2 (base, up to 36) + 1 ('#') +
		 *	number of bits in the mksh_uari_t + 1 (NUL)
		 */
		char strbuf[1 + 2 + 1 + 8 * sizeof(mksh_uari_t) + 1];
		const char *digits = (vp->flag & UCASEV_AL) ?
		    digits_uc : digits_lc;

		s = strbuf + sizeof(strbuf);
		if (vp->flag & INT_U)
			n = vp->val.u;
		else
			n = (vp->val.i < 0) ? -vp->val.u : vp->val.u;
		base = (vp->type == 0) ? 10U : (unsigned int)vp->type;

		if (base == 1 && n == 0)
			base = 2;
		if (base == 1) {
			size_t sz = 1;

			*(s = strbuf) = '1';
			s[1] = '#';
			if (!UTFMODE || ((n & 0xFF80) == 0xEF80))
				/* OPTU-16 -> raw octet */
				s[2] = n & 0xFF;
			else
				sz = utf_wctomb(s + 2, n);
			s[2 + sz] = '\0';
		} else {
			*--s = '\0';
			do {
				*--s = digits[n % base];
				n /= base;
			} while (n != 0);
			if (base != 10) {
				*--s = '#';
				*--s = digits[base % 10];
				if (base >= 10)
					*--s = digits[base / 10];
			}
			if (!(vp->flag & INT_U) && vp->val.i < 0)
				*--s = '-';
		}
		if (vp->flag & (RJUST|LJUST))
			/* case already dealt with */
			s = formatstr(vp, s);
		else
			strdupx(s, s, ATEMP);
	}
	return (s);
}
Пример #5
0
/*
 * cmd is one of:
 *    'p': normal print
 *    'h': just print headwords
 *    'P': print raw
 */
void
pgwprintentry(Entry e, int cmd)
{
    char *p, *pe;
    int t;
    long r, rprev, rlig;
    Rune *transtab;

    p = e.start;
    pe = e.end;
    transtab = normtab;
    rprev = NONE;
    changett(0, 0, 0);
    curentry = e;
    if(cmd == 'h')
        outinhibit = 1;
    while(p < pe) {
        if(cmd == 'r') {
            outchar(*p++);
            continue;
        }
        r = transtab[(*p++)&0x7F];
        if(r < NONE) {
            /* Emit the rune, but buffer in case of ligature */
            if(rprev != NONE)
                outrune(rprev);
            rprev = r;
        } else if(r == SPCS) {
            /* Start of special character name */
            p = getspec(p, pe);
            r = lookassoc(spectab, asize(spectab), spec);
            if(r == -1) {
                if(debug)
                    err("spec %ld %d %s",
                        e.doff, cursize, spec);
                r = L'�';
            }
            if(r >= LIGS && r < LIGE) {
                /* handle possible ligature */
                rlig = liglookup(r, rprev);
                if(rlig != NONE)
                    rprev = rlig;	/* overwrite rprev */
                else {
                    /* could print accent, but let's not */
                    if(rprev != NONE) outrune(rprev);
                    rprev = NONE;
                }
            } else if(r >= MULTI && r < MULTIE) {
                if(rprev != NONE) {
                    outrune(rprev);
                    rprev = NONE;
                }
                outrunes(multitab[r-MULTI]);
            } else if(r == PAR) {
                if(rprev != NONE) {
                    outrune(rprev);
                    rprev = NONE;
                }
                outnl(1);
            } else {
                if(rprev != NONE) outrune(rprev);
                rprev = r;
            }
        } else if(r == TAGS) {
            /* Start of tag name */
            if(rprev != NONE) {
                outrune(rprev);
                rprev = NONE;
            }
            p = gettag(p, pe);
            t = lookassoc(tagtab, asize(tagtab), tag);
            if(t == -1) {
                if(debug)
                    err("tag %ld %d %s",
                        e.doff, cursize, tag);
                continue;
            }
            switch(t) {
            case Hw:
                if(cmd == 'h') {
                    if(!tagstarts)
                        outchar(' ');
                    outinhibit = !tagstarts;
                }
                break;
            case Sn:
                if(tagstarts) {
                    outnl(2);
                }
                break;
            case P:
                outnl(tagstarts);
                break;
            case Col:
            case Br:
            case Blockquote:
                if(tagstarts)
                    outnl(1);
                break;
            case U:
                outchar('/');
            }
        }
    }
    if(cmd == 'h') {
        outinhibit = 0;
        outnl(0);
    }
}
Пример #6
0
static int
getint(struct tbl *vp, mksh_ari_t *nump, bool arith)
{
	int c, base, neg;
	mksh_uari_t num;
	const char *s;
	bool have_base = false;

	if (vp->flag&SPECIAL)
		getspec(vp);
	/* XXX is it possible for ISSET to be set and val.s to be 0? */
	if (!(vp->flag&ISSET) || (!(vp->flag&INTEGER) && vp->val.s == NULL))
		return (-1);
	if (vp->flag&INTEGER) {
		*nump = vp->val.i;
		return (vp->type);
	}
	s = vp->val.s + vp->type;
	base = 10;
	num = 0;
	neg = 0;
	if (arith && s[0] == '0' && (s[1] | 0x20) == 'x') {
		s += 2;
		base = 16;
		have_base = true;
	}
#ifdef MKSH_LEGACY_MODE
	if (arith && s[0] == '0' && ksh_isdigit(s[1]) &&
	    !(vp->flag & ZEROFIL)) {
		/* interpret as octal (deprecated) */
		base = 8;
		have_base = true;
	}
#endif
	while ((c = *s++)) {
		if (c == '-') {
			neg++;
			continue;
		} else if (c == '#') {
			if (have_base || num < 1 || num > 36)
				return (-1);
			base = (int)num;
			if (base == 1) {
				unsigned int wc;

				if (!UTFMODE)
					wc = *(const unsigned char *)s;
				else if (utf_mbtowc(&wc, s) == (size_t)-1)
					/* OPTU-8 -> OPTU-16 */
					/*
					 * (with a twist: 1#\uEF80 converts
					 * the same as 1#\x80 does, thus is
					 * not round-tripping correctly XXX)
					 */
					wc = 0xEF00 + *(const unsigned char *)s;
				*nump = (mksh_ari_t)wc;
				return (1);
			}
			num = 0;
			have_base = true;
			continue;
		} else if (ksh_isdigit(c))
			c -= '0';
		else if (ksh_islower(c))
			c -= 'a' - 10;
		else if (ksh_isupper(c))
			c -= 'A' - 10;
		else
			return (-1);
		if (c < 0 || c >= base)
			return (-1);
		num = num * base + c;
	}
	*nump = neg ? -((mksh_ari_t)num) : (mksh_ari_t)num;
	return (base);
}