#include	"defs.h"
#include	"global.h"

char *
alloc_check(p, e)
char *p, *e;
{
    if (p == NULL)
	Fatal("can't malloc space for %s", e);
    return p;
}

makeuint(s, n)		/* return n byte quantity from string */
byte *s;
int n;
{
    int x;	/* number being constructed */

    x = 0;
    while (n--)  {
	x <<= 8;
	x |= *s++;
    }
    return x;
}

makeint(s, n)		/* return n byte quantity from string */
byte *s;
int n;
{
    int n1;		/* number of bytes	    */
    int x;	/* number being constructed */

    x = *s++;		/* get first (high-order) byte */
    n1 = n--;
    while (n--)  {
	x <<= 8;
	x |= *s++;
    }

    /* NOTE: This code assumes that the right-shift is an arithmetic, rather
    than logical, shift which will propagate the sign bit right.   According
    to Kernighan and Ritchie, this is compiler dependent! */

    x<<=32-8*n1;
    x>>=32-8*n1;  /* sign extend */

    return x;
}

htoi(s, se)		/* hex string to int */
char *s, **se;
{
    int x;

    for (x = 0; ; s++) {
	if ('0' <= *s && *s <= '9')
	    x = x*16+*s-'0';
	else if ('a' <= *s && *s <= 'f')
	    x = x*16+*s-'a'+10;
	else if ('A' <= *s && *s <= 'F')
	    x = x*16+*s-'A'+10;
	else {
	    *se = s;
	    return x;
	}
    }
}

numstr(s)
char *s;
{
    for (; *s != '\0'; s++)
	if (!isdigit(*s))
	    return FALSE;
    return TRUE;
}

char *
strsave(s)
char *s;
{
    char *t;
    int len;

    if ((t = malloc((unsigned)(len = strlen(s)+1))) == NULL)
	Fatal("cannot save string %s", s);
    bcopy(s, t, len);
    return t;
}

/* getstrtok:
 *   find the first c in d, put '\0' there, and let *e point the next position.
 */
getstrtok(d, c, e)
char *d;
char c;
char **e;
{
    for (; *d != c && *d != '\0'; d++)
	;
    if (*d == c) {
	*d = '\0';
	*e = d+1;
	return TRUE;
    }
    return FALSE;
}

skipstrblank(d, e)
char *d;
char **e;
{
    for (; *d == ' ' || *d == '\t'; d++)
	;
    *e = d;
}


#define	LOWP	16
#define	FIXP	20
#define	LOWMASK	((1<<LOWP)-1)
#define	D	(1<<(FIXP-LOWP))
#define	H	(1<<(2*LOWP-FIXP))
#define	TPT(x, y)	((x)<<(y))	/* x * 2^y */
#define	DPT(x, y)	((x)>>(y))	/* x / 2^y */

scale_exact(s, d)
int s, d;
{
    int sign;
    unsigned int s1, s0, d1, d0;

    if (s < 0) {
	sign = -1;
	s *= -1;
    } else
	sign = 1;
    s0 = s & LOWMASK;
    d0 = d & LOWMASK;
    s1 = s >> LOWP;
    d1 = d >> LOWP;
    return (sign *
	    (TPT(s1*d1, 2*LOWP-FIXP) +
	     DPT(s1*d0+s0*d1 + DPT(s0*d0, LOWP), FIXP-LOWP))
	    );
}
