コード例 #1
0
ファイル: main.c プロジェクト: n-t-roff/DWB3.3
static void
getdata(void)
{
	char *p, buf[1000], buf1[100];
	int ln;

	curfile->lineno = 0;
	printlf(1, curfile->fname);
	while (fgets(buf, sizeof buf, curfile->fin) != NULL) {
		curfile->lineno++;
		if (*buf == '.' && *(buf+1) == 'P' && *(buf+2) == 'S') {
			for (p = &buf[3]; *p == ' '; p++)
				;
			if (*p++ == '<') {
				Infile svfile;
				svfile = *curfile;
				sscanf(p, "%s", buf1);
				if ((curfile->fin=fopen(buf1, "r")) == NULL)
					ERROR "can't open %s", buf1 FATAL;
				curfile->fname = tostring(buf1);
				getdata();
				fclose(curfile->fin);
				free(curfile->fname);
				*curfile = svfile;
				printlf(curfile->lineno, curfile->fname);
				continue;
			}
			reset();
			yyparse();
			anyerr += synerr;
			/* yylval.i now contains 'E' or 'F' from .PE or .PF */

			deltx = (xmax - xmin) / getfval("scale");
			delty = (ymax - ymin) / getfval("scale");
			if (buf[3] == ' ') {	/* next things are wid & ht */
				if (sscanf(&buf[4],"%lf %lf", &deltx, &delty) < 2)
					delty = deltx * (ymax-ymin) / (xmax-xmin);
#if 0
				/* else {
				 *	double xfac, yfac; */
				 *	xfac = deltx / (xmax-xmin);
				 *	yfac = delty / (ymax-ymin);
				 *	if (xfac <= yfac)
				 *		delty = xfac * (ymax-ymin);
				 *	else
				 *		deltx = yfac * (xmax-xmin);
				 *}
				 */
#endif
			}
			dprintf("deltx = %g, delty = %g\n", deltx, delty);
			if (codegen && !synerr) {
				openpl(&buf[3]);	/* puts out .PS, with ht & wid stuck in */
				printlf(curfile->lineno+1, NULL);
				print();	/* assumes \n at end */
				closepl(yylval.i);	/* does the .PE/F */
			}
			printlf(curfile->lineno+1, NULL);
			fflush(stdout);
		} else if (buf[0] == '.' && buf[1] == 'l' && buf[2] == 'f') {
コード例 #2
0
ファイル: pltroff.c プロジェクト: bapt/heirloom-doctools
void openpl(char *s)	/* initialize device; s is residue of .PS invocation line */
{
	double maxw, maxh, ratio = 1;
	double odeltx = deltx, odelty = delty;

	hpos = vpos = 0;
	maxw = getfval("maxpswid");
	maxh = getfval("maxpsht");
	if (deltx > maxw) {	/* shrink horizontal */
		ratio = maxw / deltx;
		deltx *= ratio;
		delty *= ratio;
	}
	if (delty > maxh) {	/* shrink vertical */
		ratio = maxh / delty;
		deltx *= ratio;
		delty *= ratio;
	}
	if (ratio != 1) {
		fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty);
		fprintf(stderr, " %g X %g\n", deltx, delty);
	}
	space(xmin, ymin, xmax, ymax);
	printf(".\\\" %g %g %g %g\n", xmin, ymin, xmax, ymax);
	printf(".\\\" %.3fi %.3fi %.3fi %.3fi\n",
		xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
	printf(".nr 00 \\n(.u\n");
	printf(".nf\n");
	printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
		/* assumes \n comes as part of s */
}
コード例 #3
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *arith(Node **a, int n)	/* a[0] + a[1], etc.  also -a[0] */
{
	Awkfloat i, j = 0;
	double v;
	Cell *x, *y, *z;

	x = execute(a[0]);
	i = getfval(x);
	tempfree(x);
	if (n != UMINUS) {
		y = execute(a[1]);
		j = getfval(y);
		tempfree(y);
	}
	z = gettemp();
	switch (n) {
	case ADD:
		i += j;
		break;
	case MINUS:
		i -= j;
		break;
	case MULT:
		i *= j;
		break;
	case DIVIDE:
		if (j == 0)
			ERROR "division by zero" FATAL;
		i /= j;
		break;
	case MOD:
		if (j == 0)
			ERROR "division by zero in mod" FATAL;
		modf(i/j, &v);
		i = i - j * v;
		break;
	case UMINUS:
		i = -i;
		break;
	case POWER:
		if (j >= 0 && modf(j, &v) == 0.0)	/* pos integer exponent */
			i = ipow(i, (int) j);
		else
			i = errcheck(pow(i, j), "pow");
		break;
	default:	/* can't happen */
		ERROR "illegal arithmetic operator %d", n FATAL;
	}
	setfval(z, i);
	return(z);
}
コード例 #4
0
Cell *substr(Node **a, int nnn)		/* substr(a[0], a[1], a[2]) */
{
	int k, m, n;
	char *s;
	int temp;
	Cell *x, *y, *z = 0;

	x = execute(a[0]);
	y = execute(a[1]);
	if (a[2] != 0)
		z = execute(a[2]);
	s = getsval(x);
	k = strlen(s) + 1;
	if (k <= 1) {
		tempfree(x);
		tempfree(y);
		if (a[2] != 0) {
			tempfree(z);
		}
		x = gettemp();
		setsval(x, "");
		return(x);
	}
	m = (int) getfval(y);
	if (m <= 0)
		m = 1;
	else if (m > k)
		m = k;
	tempfree(y);
	if (a[2] != 0) {
		n = (int) getfval(z);
		tempfree(z);
	} else
		n = k - 1;
	if (n < 0)
		n = 0;
	else if (n > k - m)
		n = k - m;
	   dprintf( ("substr: m=%d, n=%d, s=%s\n", m, n, s) );
	y = gettemp();
	temp = s[n+m-1];	/* with thanks to John Linderman */
	s[n+m-1] = '\0';
	setsval(y, s + m - 1);
	s[n+m-1] = temp;
	tempfree(x);
	return(y);
}
コード例 #5
0
ファイル: attrs.c プロジェクト: n-t-roff/DWB3.3
void
checktextcolor (obj *p) {
	if (p->o_nt2 > p->o_nt1) {
		if (p->o_text == -1)
			p->o_text = getfval("textcolor");
		p->o_text = checkcolor((double)p->o_text);
	}
}
コード例 #6
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *jump(Node **a, int n)	/* break, continue, next, nextfile, return */
{
	Cell *y;

	switch (n) {
	case EXIT:
		if (a[0] != NULL) {
			y = execute(a[0]);
			errorflag = getfval(y);
			tempfree(y);
		}
		longjmp(env, 1);
	case RETURN:
		if (a[0] != NULL) {
			y = execute(a[0]);
			if ((y->tval & (STR|NUM)) == (STR|NUM)) {
				setsval(fp->retval, getsval(y));
				fp->retval->fval = getfval(y);
				fp->retval->tval |= NUM;
			}
			else if (y->tval & STR)
				setsval(fp->retval, getsval(y));
			else if (y->tval & NUM)
				setfval(fp->retval, getfval(y));
			else		/* can't happen */
				ERROR "bad type variable %d", y->tval FATAL;
			tempfree(y);
		}
		return(jret);
	case NEXT:
		return(jnext);
	case NEXTFILE:
		nextfile();
		return(jnextfile);
	case BREAK:
		return(jbreak);
	case CONTINUE:
		return(jcont);
	default:	/* can't happen */
		ERROR "illegal jump type %d", n FATAL;
	}
	return 0;	/* not reached */
}
コード例 #7
0
ファイル: pltroff.c プロジェクト: n-t-roff/DWB3.3
void
openpl(char *s)	/* initialize device */
	/* char *s;	/ * residue of .PS invocation line */
{
	double maxw, maxh, ratio = 1;
	double odeltx = deltx, odelty = delty;

	hpos = vpos = 0;
	maxw = getfval("maxpswid");
	maxh = getfval("maxpsht");
/*	if (deltx > getfval("maxpswid") || delty > getfval("maxpsht")) {	/ * 8.5x11 inches max * /
 *		fprintf(stderr, "pic: %g X %g picture shrunk to", deltx, delty);
 *		maxdelt = max(deltx, delty);
 *		deltx *= 7/maxdelt;	/ * screwed up anyway; * /
 *		delty *= 7/maxdelt;	/ * make it 7x7 so someone can see it * /
 *		fprintf(stderr, " %g X %g\n", deltx, delty);
 *	}
 */
	if (deltx > maxw) {	/* shrink horizontal */
		ratio = maxw / deltx;
		deltx *= ratio;
		delty *= ratio;
	}
	if (delty > maxh) {	/* shrink vertical */
		ratio = maxh / delty;
		deltx *= ratio;
		delty *= ratio;
	}
	if (ratio != 1) {
		fprintf(stderr, "pic: %g X %g picture shrunk to", odeltx, odelty);
		fprintf(stderr, " %g X %g\n", deltx, delty);
	}
	space(xmin, ymin, xmax, ymax);
	printf("... %g %g %g %g\n", xmin, ymin, xmax, ymax);
	printf("... %.3fi %.3fi %.3fi %.3fi\n",
		xconv(xmin), yconv(ymin), xconv(xmax), yconv(ymax));
	printf(".nr 00 \\n(.u\n");
	printf(".nf\n");
	printf(".PS %.3fi %.3fi %s", yconv(ymin), xconv(xmax), s);
		/* assumes \n comes as part of s */
}
コード例 #8
0
ファイル: for.c プロジェクト: 99years/plan9
void nextfor(void)	/* do one iteration of a for loop */
{
	/* BUG:  this should depend on op and direction */
	if (getfval(forp->var) > SLOP * forp->to) {	/* loop is done */
		free(forp->str);
		if (--forp < forstk)
			ERROR "forstk popped too far" FATAL;
	} else {		/* another iteration */
		pushsrc(String, "\nEndfor\n");
		pushsrc(String, forp->str);
	}
}
コード例 #9
0
ファイル: main.c プロジェクト: n-t-roff/DWB3.3
void
checkscale(char *s)	/* if s is "scale", adjust default variables */
{
	int i;
	double scale;

	if (strcmp(s, "scale") == 0) {
		scale = getfval("scale");
		for (i = 1; defaults[i].name != NULL; i++)
			if (defaults[i].scalable)
				setfval(defaults[i].name, defaults[i].val * scale);
	}
}
コード例 #10
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *indirect(Node **a, int n)	/* $( a[0] ) */
{
	Cell *x;
	int m;
	char *s;

	x = execute(a[0]);
	m = getfval(x);
	if (m == 0 && !isnumber(s = getsval(x)))	/* suspicion! */
		ERROR "illegal field $(%s), name \"%s\"", s, x->nval FATAL;
  /* can x->nval ever be null??? */
		/* ERROR "illegal field $(%s)", s FATAL; */
	tempfree(x);
	x = fieldadr(m);
	x->ctype = OCELL;
	x->csub = CFLD;
	return(x);
}
コード例 #11
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *incrdecr(Node **a, int n)		/* a[0]++, etc. */
{
	Cell *x, *z;
	int k;
	Awkfloat xf;

	x = execute(a[0]);
	xf = getfval(x);
	k = (n == PREINCR || n == POSTINCR) ? 1 : -1;
	if (n == PREINCR || n == PREDECR) {
		setfval(x, xf + k);
		return(x);
	}
	z = gettemp();
	setfval(z, xf);
	setfval(x, xf + k);
	tempfree(x);
	return(z);
}
コード例 #12
0
ファイル: attrs.c プロジェクト: n-t-roff/DWB3.3
void
primattrs(obj *p, struct objattr *obat)	/* note: ht, wid, rad and layer are set elsewhere   */
			/*	 because of nonuniformities in their design */
		/*	 (this could be further rationalized!)	    */
{
	int	n;
	float	x;

	p->o_attr |= obat->a_flags;
	p->o_text  = obat->a_tcolor;
	checktextcolor(p);
	if (obat->a_flags & FILLED) {
		if (obat->a_pcolor == -1.)
			obat->a_pcolor = getfval ("fillcolor");
		p->o_fill = checkcolor((double)obat->a_pcolor);
	}
	if (obat->a_flags & EDGED) {
		if (obat->a_weight == -1.)
			obat->a_weight = getfval ("lineweight");
		if (obat->a_weight >= 0.)
			p->o_weight = obat->a_weight;
		if (obat->a_lcolor == -1.)
			obat->a_lcolor = getfval ("linecolor");
		p->o_color = checkcolor((double)obat->a_lcolor);
		if ((n = (int)getfval("linecap")) >= 0)
			p->o_attr |= (1 + n%3)*LINECAP;
		if ((n = (int)getfval("linejoin")) >= 0)
			p->o_attr |= (1 + n%3)*JOIN;
		if (n == 0) {				/* mitre join */
			x = getfval("miterlimit");
			if (x >= 1) {
				for (n = 1; n < 8; n++)
					if (miters[n] == 0 || miters[n] == x)
						break;
				if (n == 8)
					for (n = 1; n < 7; ++n)
						miters[n] = miters[n+1];
				miters[n] = x;
				p->o_attr |= n * MITER;
			}
		}
	}
	else
		p->o_weight = 0;
	if (obat->a_dashpat.a != NULL && obat->a_dashpat.a[1] == -1) /* dots */
		if ((obat->a_dashpat.a[1] = p->o_weight) == 0)
			obat->a_dashpat.a[1] = 1/(pgscale*2);
	p->o_ddpat = obat->a_dashpat;
}
コード例 #13
0
Cell *indirect(Node **a, int n)	/* $( a[0] ) */
{
	Awkfloat val;
	Cell *x;
	int m;
	char *s;

	x = execute(a[0]);
	val = getfval(x);	/* freebsd: defend against super large field numbers */
	if ((Awkfloat)INT_MAX < val)
		FATAL("trying to access out of range field %s", x->nval);
	m = (int) val;
	if (m == 0 && !is_number(s = getsval(x)))	/* suspicion! */
		FATAL("illegal field $(%s), name \"%s\"", s, x->nval);
		/* BUG: can x->nval ever be null??? */
	tempfree(x);
	x = fieldadr(m);
	x->ctype = OCELL;	/* BUG?  why are these needed? */
	x->csub = CFLD;
	return(x);
}
コード例 #14
0
ファイル: tran.c プロジェクト: mluszczyk/so-minix
char *setsval(Cell *vp, const char *s)	/* set string val of a Cell */
{
    char *t;
    int fldno;
    Awkfloat f;

    dprintf( ("starting setsval %p: %s = \"%s\", t=%o, r,f=%d,%d\n",
              vp, NN(vp->nval), s, vp->tval, donerec, donefld) );
    if ((vp->tval & (NUM | STR)) == 0)
        funnyvar(vp, "assign to");
    if (isfld(vp)) {
        donerec = 0;	/* mark $0 invalid */
        fldno = atoi(vp->nval);
        if (fldno > *NF)
            newfld(fldno);
        dprintf( ("setting field %d to %s (%p)\n", fldno, s, s) );
    } else if (isrec(vp)) {
        donefld = 0;	/* mark $1... invalid */
        donerec = 1;
    }
    t = tostring(s);	/* in case it's self-assign */
    if (freeable(vp))
        xfree(vp->sval);
    vp->tval &= ~NUM;
    vp->tval |= STR;
    vp->tval &= ~DONTFREE;
    dprintf( ("setsval %p: %s = \"%s (%p) \", t=%o r,f=%d,%d\n",
              vp, NN(vp->nval), t,t, vp->tval, donerec, donefld) );

    vp->sval = t;
    if (&vp->fval == NF) {
        donerec = 0;	/* mark $0 invalid */
        f = getfval(vp);
        setlastfld(f);
        dprintf( ("setting NF to %g\n", f) );
    }

    return(vp->sval);
}
コード例 #15
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *call(Node **a, int n)	/* function call.  very kludgy and fragile */
{
	static Cell newcopycell = { OCELL, CCOPY, 0, (char *) "", 0.0, NUM|STR|DONTFREE };
	int i, ncall, ndef;
	Node *x;
	Cell *args[NARGS], *oargs[NARGS], *y, *z, *fcn;
	char *s;

	fcn = execute(a[0]);	/* the function itself */
	s = fcn->nval;
	if (!isfunc(fcn))
		ERROR "calling undefined function %s", s FATAL;
	if (frame == NULL) {
		fp = frame = (struct Frame *) calloc(nframe += 100, sizeof(struct Frame));
		if (frame == NULL)
			ERROR "out of space for stack frames calling %s", s FATAL;
	}
	for (ncall = 0, x = a[1]; x != NULL; x = x->nnext)	/* args in call */
		ncall++;
	ndef = (int) fcn->fval;			/* args in defn */
	dprintf( ("calling %s, %d args (%d in defn), fp=%d\n", s, ncall, ndef, fp-frame) );
	if (ncall > ndef)
		ERROR "function %s called with %d args, uses only %d",
			s, ncall, ndef WARNING;
	if (ncall + ndef > NARGS)
		ERROR "function %s has %d arguments, limit %d", s, ncall+ndef, NARGS FATAL;
	for (i = 0, x = a[1]; x != NULL; i++, x = x->nnext) {	/* get call args */
		dprintf( ("evaluate args[%d], fp=%d:\n", i, fp-frame) );
		y = execute(x);
		oargs[i] = y;
		dprintf( ("args[%d]: %s %f <%s>, t=%o\n",
			   i, y->nval, y->fval, isarr(y) ? "(array)" : (char*) y->sval, y->tval) );
		if (isfunc(y))
			ERROR "can't use function %s as argument in %s", y->nval, s FATAL;
		if (isarr(y))
			args[i] = y;	/* arrays by ref */
		else
			args[i] = copycell(y);
		tempfree(y);
	}
	for ( ; i < ndef; i++) {	/* add null args for ones not provided */
		args[i] = gettemp();
		*args[i] = newcopycell;
	}
	fp++;	/* now ok to up frame */
	if (fp >= frame + nframe) {
		int dfp = fp - frame;	/* old index */
		frame = (struct Frame *)
			realloc((char *) frame, (nframe += 100) * sizeof(struct Frame));
		if (frame == NULL)
			ERROR "out of space for stack frames in %s", s FATAL;
		fp = frame + dfp;
	}
	fp->fcncell = fcn;
	fp->args = args;
	fp->nargs = ndef;	/* number defined with (excess are locals) */
	fp->retval = gettemp();

	dprintf( ("start exec of %s, fp=%d\n", s, fp-frame) );
	y = execute((Node *)(fcn->sval));	/* execute body */
	dprintf( ("finished exec of %s, fp=%d\n", s, fp-frame) );

	for (i = 0; i < ndef; i++) {
		Cell *t = fp->args[i];
		if (isarr(t)) {
			if (t->csub == CCOPY) {
				if (i >= ncall) {
					freesymtab(t);
					t->csub = CTEMP;
				} else {
					oargs[i]->tval = t->tval;
					oargs[i]->tval &= ~(STR|NUM|DONTFREE);
					oargs[i]->sval = t->sval;
					tempfree(t);
				}
			}
		} else if (t != y) {	/* kludge to prevent freeing twice */
			t->csub = CTEMP;
			tempfree(t);
		}
	}
	tempfree(fcn);
	if (isexit(y) || isnext(y) || isnextfile(y))
		return y;
	tempfree(y);		/* this can free twice! */
	z = fp->retval;			/* return value */
	dprintf( ("%s returns %g |%s| %o\n", s, getfval(z), getsval(z), z->tval) );
	fp--;
	return(z);
}
コード例 #16
0
ファイル: attrs.c プロジェクト: n-t-roff/DWB3.3
void
miscattrs(Attr *ap, struct objattr *obat) {
	float	*fp;
	int	n;

	switch (ap->a_type) {
		case FONT:
			reset_font((double)ap->a_val.f);
			break;
		case SIZE:
			reset_size(ap->a_sub, (double)ap->a_val.f);
			break;
		case SPACE:
			reset_space(ap->a_sub, (double)ap->a_val.f);
			break;
		case TEXTATTR:
			if (ap->a_val.p != NULL)
				savetext(ap->a_sub, ap->a_val.p);
			else
	/* These type values should be propagated back to other strings */
	/* Maybe by calling reset_type, to be added to textgen.c */
				text[ntext-1].t_type = ap->a_sub;
						/* ??? can this ever happen */
						/* except after a previous  */
						/* text in the same object? */
			break;
		case NOEDGE:
			obat->a_flags &= ~EDGED;
			break;
		case LAYER:
			obat->a_layer = ap->a_val.f;
			break;
		case LWEIGHT:
			obat->a_weight = ap->a_val.f;
			break;
		case LCOLOR:
			obat->a_lcolor = ap->a_val.f;
			break;
		case PCOLOR:
			obat->a_flags |= FILLED;
			if (ap->a_sub != DEFAULT)
				obat->a_pcolor = ap->a_val.f;
			break;
		case TCOLOR:
			obat->a_tcolor = ap->a_val.f;
			break;
		case DOT:
		case DASH:
			n = ap->a_type == DOT ? 3 : 2;
			if ((fp = (float *)malloc(n * sizeof(float))) == NULL) {
				yyerror("out of space in miscattrs");
				break;
			}
			*fp = --n;
			fp[n] = (ap->a_sub == DEFAULT ? getfval("dashwid")
						      : ap->a_val.f);
			if (n == 2)
				fp[1] = -1;	/* fill in later, from weight */
			ap->a_val.a = fp;
			/* and fall through to the general case */
		case DASHPAT:
			obat->a_flags |= DOTDASH;
			obat->a_dashpat.a = ap->a_val.a;
			break;
		case HEIGHT:
			obat->a_ht = ap->a_val.f;
			break;
		case WIDTH:
			obat->a_wid = ap->a_val.f;
			break;
		case RADIUS:
			obat->a_rad = ap->a_val.f;
			break;
		case DIAMETER:
			obat->a_rad = ap->a_val.f / 2;
			break;
	}
}
コード例 #17
0
ファイル: attrs.c プロジェクト: n-t-roff/DWB3.3
double
setattr(obj *p, int type, double val) {
	int	cw_switch;
	double	x, y;
	obj	*q;

	if (p->o_type == BLOCK) {
		for (q = p->o_next; q != p->o_val[N_VAL].o; q = q->o_next)
			setattr (q, type, val);
	}
	else if (p->o_type <= TEXT) switch (type) {

case TCOLOR:	if (val >= 0.0 || checkcolor(val) >= 0.0)
			p->o_text = val;
		break;
case LCOLOR:	if (val >= 0.0 || checkcolor(val) >= 0.0)
			p->o_color = val;
		break;
case PCOLOR:	if (val < 0.0 || checkcolor(val) < 0.0)
			p->o_attr &= ~FILLED;
		else {
			p->o_fill = val;	/* ignored for TEXT? */
			p->o_attr |= FILLED;
		}
		break;
case LAYER:	if (val < -128) val = -128; else if (val > 127) val = 127;
		p->o_layer = (short)val;
		if (val > getfval("maxlayer"))
			setfval ("maxlayer", val);
		break;
case LWEIGHT:	p->o_weight = val;
		break;
case NOEDGE:	if (val != 0.0)
			p->o_attr &= ~EDGED;
		else
			p->o_attr |= EDGED;
		break;

case CCW:
case CW:	if (p->o_type == ARC) {
			cw_switch = (p->o_attr & CW_ARC);
			if (type == CW)
				cw_switch = !cw_switch;
			if (cw_switch) {
				x = p->o_val[N_VAL+2].f;
				y = p->o_val[N_VAL+3].f;
				p->o_val[N_VAL+2] = p->o_val[N_VAL+4];
				p->o_val[N_VAL+3] = p->o_val[N_VAL+5];
    /* exchange from & to */	p->o_val[N_VAL+4].f = x;
				p->o_val[N_VAL+5].f = y;
				p->o_attr ^= (p->o_attr & CW_ARC);
			}
		}
		break;
case DIAMETER:	val /= 2;
case RADIUS:	switch (p->o_type) {
			case ARROW:
			case LINE:	
			case BOX:
			case ARC:
			case SECTOR:	p->o_val[N_VAL].f = val;
					break;
			case CIRCLE:
			case ELLIPSE:	p->o_wid = val * 2;
					break;
		}
		break;
case WIDTH:	p->o_wid = val;
		break;
case HEIGHT:	p->o_ht = val;
		break;
default:	yyerror ("can't happen setattr");
	}
	return val;
}
コード例 #18
0
ファイル: linegen.c プロジェクト: n-t-roff/DWB3.3
obj *linegen(int type)
{
	static double prevdx = HT;
	static double prevdy = 0;
	static double prevw = HT10;
	static double prevh = HT5;
	int i, j, some, head, ddtype, invis, chop;
	double ddval, chop1, chop2, x0, y0, x1, y1;
	double sin(), cos(), atan2(), theta;
	double defx, defy;
	obj *p, *ppos;
	static int xtab[] = { 1, 0, -1, 0 };	/* R=0, U=1, L=2, D=3 */
	static int ytab[] = { 0, 1, 0, -1 };
	double dx[500], dy[500];
	int ndxy;
	double nx, ny;
	Attr *ap;

	nx = curx;
	ny = cury;
	defx = getfval("linewid");
	defy = getfval("lineht");
	prevh = getfval("arrowht");
	prevw = getfval("arrowwid");
	dx[0] = dy[0] = ndxy = some = head = invis = 0;
	chop = chop1 = chop2 = 0;
	ddtype = ddval = 0;
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		case HEAD:
			head += ap->a_val.i;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case CHOP:
			if (chop++ == 0)
				chop1 = chop2 = ap->a_val.f;
			else
				chop2 = ap->a_val.f;
			break;
		case DOT:
		case DASH:
			ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		case SAME:
			dx[ndxy] = prevdx;
			dy[ndxy] = prevdy;
			some++;
			break;
		case LEFT:
			dx[ndxy] -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
			some++;
			hvmode = L_DIR;
			break;
		case RIGHT:
			dx[ndxy] += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
			some++;
			hvmode = R_DIR;
			break;
		case UP:
			dy[ndxy] += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
			some++;
			hvmode = U_DIR;
			break;
		case DOWN:
			dy[ndxy] -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
			some++;
			hvmode = D_DIR;
			break;
		case HEIGHT:	/* length of arrowhead */
			prevh = ap->a_val.f;
			break;
		case WIDTH:	/* width of arrowhead */
			prevw = ap->a_val.f;
			break;
		case TO:
			if (some) {
				nx += dx[ndxy];
				ny += dy[ndxy];
				ndxy++;
				dx[ndxy] = dy[ndxy] = some = 0;
			}
			ppos = attr[i].a_val.o;
			dx[ndxy] = ppos->o_x - nx;
			dy[ndxy] = ppos->o_y - ny;
			some++;
			break;
		case BY:
			if (some) {
				nx += dx[ndxy];
				ny += dy[ndxy];
				ndxy++;
				dx[ndxy] = dy[ndxy] = some = 0;
			}
			ppos = ap->a_val.o;
			dx[ndxy] = ppos->o_x;
			dy[ndxy] = ppos->o_y;
			some++;
			break;
		case THEN:	/* turn off any previous accumulation */
			if (some) {
				nx += dx[ndxy];
				ny += dy[ndxy];
				ndxy++;
				dx[ndxy] = dy[ndxy] = some = 0;
			}
			break;
		case FROM:
		case AT:
			ppos = ap->a_val.o;
			nx = curx = ppos->o_x;
			ny = cury = ppos->o_y;
			break;
		}
	}
	if (some) {
		nx += dx[ndxy];
		ny += dy[ndxy];
		ndxy++;
		defx = dx[ndxy-1];
		defy = dy[ndxy-1];
	} else {
		defx *= xtab[hvmode];
		defy *= ytab[hvmode];
		dx[ndxy] = defx;
		dy[ndxy] = defy;
		ndxy++;
		nx += defx;
		ny += defy;
	}
	prevdx = defx;
	prevdy = defy;
	if (chop) {
		if (chop == 1 && chop1 == 0)	/* just said "chop", so use default */
			chop1 = chop2 = getfval("circlerad");
		theta = atan2(dy[0], dx[0]);
		x0 = chop1 * cos(theta);
		y0 = chop1 * sin(theta);
		curx += x0;
		cury += y0;
		dx[0] -= x0;
		dy[0] -= y0;

		theta = atan2(dy[ndxy-1], dx[ndxy-1]);
		x1 = chop2 * cos(theta);
		y1 = chop2 * sin(theta);
		nx -= x1;
		ny -= y1;
		dx[ndxy-1] -= x1;
		dy[ndxy-1] -= y1;
		dprintf("chopping %g %g %g %g; cur=%g,%g end=%g,%g\n",
			x0, y0, x1, y1, curx, cury, nx, ny);
	}
	p = makenode(type, 5 + 2 * ndxy);
	curx = p->o_val[0] = nx;
	cury = p->o_val[1] = ny;
	if (head || type == ARROW) {
		p->o_nhead = getfval("arrowhead");
		p->o_val[2] = prevw;
		p->o_val[3] = prevh;
		if (head == 0)
			head = HEAD2;	/* default arrow head */
	}
	p->o_attr = head | invis | ddtype;
	p->o_val[4] = ndxy;
	nx = p->o_x;
	ny = p->o_y;
	for (i = 0, j = 5; i < ndxy; i++, j += 2) {
		p->o_val[j] = dx[i];
		p->o_val[j+1] = dy[i];
		if (type == LINE || type == ARROW)
			extreme(nx += dx[i], ny += dy[i]);
		else if (type == SPLINE && i < ndxy-1) {
			/* to compute approx extreme of spline at p,
			 * compute midway between p-1 and p+1,
			 * then go 3/4 from there to p */
			double ex, ey, xi, yi, xi1, yi1;
			xi = nx + dx[i]; yi = ny + dy[i];	/* p */
			xi1 = xi + dx[i+1]; yi1 = yi + dy[i+1];	/* p+1 */
			ex = (nx+xi1)/2; ey = (ny+yi1)/2;	/* midway */
			ex += 0.75*(xi-ex); ey += 0.75*(yi-ey);
			extreme(ex, ey);
			nx = xi; ny = yi;
		}
			
	}
	p->o_ddval = ddval;
	if (dbg) {
		printf("S or L from %g %g to %g %g with %d elements:\n", p->o_x, p->o_y, curx, cury, ndxy);
		for (i = 0, j = 5; i < ndxy; i++, j += 2)
			printf("%g %g\n", p->o_val[j], p->o_val[j+1]);
	}
	extreme(p->o_x, p->o_y);
	extreme(curx, cury);
	return(p);
}
コード例 #19
0
ファイル: arcgen.c プロジェクト: n-t-roff/DWB3.3
obj *
arcgen(int type)	/* handles circular and (eventually) elliptical arcs */
{
    static	double	prevwid	= HT10;
    static	double	prevht	= HT5;
    static	double	prevrad	= HT2;
    static	int	dtox[2][4]   = { { 1, -1, -1, 1 }, { 1, 1, -1, -1 } };
    static	int	dtoy[2][4]   = { { 1, 1, -1, -1 }, { -1, 1, 1, -1 } };
    static	int	dctrx[2][4]  = { { 0, -1, 0, 1 }, { 0, 1, 0, -1 } };
    static	int	dctry[2][4]  = { { 1, 0, -1, 0 }, { -1, 0, 1, 0 } };
    static	int	nexthv[2][4] = { { U_DIR, L_DIR, D_DIR, R_DIR }, {
            D_DIR,
            R_DIR, U_DIR, L_DIR
        }
    };
    struct	objattr	obat;
    double	dx2, dy2, phi, r, d, fromx, fromy, tox, toy;
    int	i, head, to, at, cw;
    obj	*p, *ppos;
    Attr	*ap;

    obat.a_ht  = getfval("arrowht");
    obat.a_wid = getfval("arrowwid");
    obat.a_rad = getfval("arcrad");
    obat.a_layer = (int)getfval("curlayer");
    obat.a_flags = EDGED;
    obat.a_weight = obat.a_lcolor = obat.a_pcolor = obat.a_tcolor = -1;
    obat.a_dashpat.a = (float *)0;
    set_text();
    fromx = curx;
    fromy = cury;
    head = to = at = cw = 0;
    for (i = 0; i < nattr; i++) {
        ap = &attr[i];
        switch (ap->a_type) {
        default:
            miscattrs(ap, &obat);
            break;
        case HEAD:
            head += ap->a_val.i;
            break;
        case CW:
            cw = 1;
            break;
        case FROM:	/* start point of arc */
            ppos = ap->a_val.o;
            fromx = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
            fromy = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
            break;
        case TO:	/* end point of arc */
            ppos = ap->a_val.o;
            tox = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
            toy = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
            to++;
            break;
        case AT:	/* center of arc */
            ppos = ap->a_val.o;
            curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
            cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
            at = 1;
            break;
        case UP:
            hvmode = U_DIR;
            break;
        case DOWN:
            hvmode = D_DIR;
            break;
        case RIGHT:
            hvmode = R_DIR;
            break;
        case LEFT:
            hvmode = L_DIR;
            break;
        case SAME:
            obat.a_ht  = prevht;
            obat.a_wid = prevwid;
            obat.a_rad = prevrad;
            break;
        }
    }
    if (!at && !to) {	/* the defaults are mostly OK */
        curx = fromx + obat.a_rad * dctrx[cw][hvmode];
        cury = fromy + obat.a_rad * dctry[cw][hvmode];
        tox  = fromx + obat.a_rad * dtox[cw][hvmode];
        toy  = fromy + obat.a_rad * dtoy[cw][hvmode];
        hvmode = nexthv[cw][hvmode];
    }
    else if (to) {		/* then compute center */
        dx2 = (tox - fromx) / 2;
        dy2 = (toy - fromy) / 2;
        phi = atan2(dy2, dx2) + (cw ? -M_PI_2 : M_PI_2);
        /*  If from, to, at (and possibly radius) are all supplied,
         *  the arc is overdetermined.  Recompute the radius (as
         *  well as at (i.e., curx and cury)) in that case.
         */
        if (at) {
            double  alpha;

            obat.a_rad = sqrt((curx - fromx) * (curx - fromx) +
                              (cury - fromy) * (cury - fromy));
            alpha = atan2(toy - cury, tox - curx) -
                    atan2(fromy - cury, fromx - curx);
            if (alpha < 0.)	alpha += 2 * M_PI;
            if ((!cw && alpha > M_PI) || (cw && alpha < M_PI))
                phi += M_PI;
        }
        else if (obat.a_rad <= 0.0)
            obat.a_rad = sqrt(dx2*dx2+dy2*dy2);
        for (r=obat.a_rad; (d = r*r - (dx2*dx2+dy2*dy2)) <= 0.0; r *= 2)
            ;	/* this kludge gets around too-small radii */
        obat.a_rad = r;
        d = sqrt(d);
        curx = fromx + dx2 + d * cos(phi);
        cury = fromy + dy2 + d * sin(phi);
    }
    else if (at && !to) {	/* do we have all the cases??? */
        tox = fromx + obat.a_rad * dtox[cw][hvmode];
        toy = fromy + obat.a_rad * dtoy[cw][hvmode];
        hvmode = nexthv[cw][hvmode];
    }
    p = makenode(type, N_VAL + 10, obat.a_layer);
    prevrad = p->o_val[N_VAL+0].f = p->o_val[N_VAL+1].f = obat.a_rad;
    prevwid = p->o_val[N_VAL+8].f = obat.a_wid;
    prevht  = p->o_val[N_VAL+9].f = obat.a_ht;
    if (cw) {	/* interchange roles of from-to and heads */
        double temp;
        temp = fromx;
        curx = fromx = tox;
        tox = temp;
        temp = fromy;
        cury = fromy = toy;
        toy = temp;
        if (head == HEAD1)
            head = HEAD2;
        else if (head == HEAD2)
            head = HEAD1;
        p->o_attr |= CW_ARC;
    }
    else {
        curx = tox;
        cury = toy;
    }
    p->o_val[N_VAL+2].f = fromx;
    p->o_val[N_VAL+3].f = fromy;
    p->o_val[N_VAL+4].f = tox;
    p->o_val[N_VAL+5].f = toy;
    if (head)
        p->o_attr |= head | arrowfill();
    primattrs(p, &obat);
    text_bounds(p);
    arc_extreme(p);
    return(p);
}
コード例 #20
0
obj *circgen(type)
{
	static float rad[2] = { HT2, WID2 };
	static float rad2[2] = { HT2, HT2 };
	static float x0, y0, x1, y1, x2, y2;
	int i, at, t, invis, ddtype, with;
	float xwith, ywith;
	float r, r2, ddval;
	obj *p, *ppos;
	Attr *ap;

	at = invis = ddtype = 0;
	with = xwith = ywith = 0;
	t = (type == CIRCLE) ? 0 : 1;
	if (type == CIRCLE)
		r = r2 = getfval("circlerad");
	else if (type == ELLIPSE) {
		r = getfval("ellipsewid") / 2;
		r2 = getfval("ellipseht") / 2;
	}
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		case RADIUS:
			r = ap->a_val.f;
			break;
		case DIAMETER:
		case WIDTH:
			r = ap->a_val.f / 2;
			break;
		case HEIGHT:
			r2 = ap->a_val.f / 2;
			break;
		case SAME:
			r = rad[t];
			r2 = rad2[t];
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case DOT:
		case DASH:
			ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		}
	}
	if (type == CIRCLE)
		r2 = r;	/* probably superfluous */
	if (with) {
		switch (with) {
		case NORTH:	ywith = -r2; break;
		case SOUTH:	ywith = r2; break;
		case EAST:	xwith = -r; break;
		case WEST:	xwith = r; break;
		case NE:	xwith = -r * 0.707; ywith = -r2 * 0.707; break;
		case SE:	xwith = -r * 0.707; ywith = r2 * 0.707; break;
		case NW:	xwith = r * 0.707; ywith = -r2 * 0.707; break;
		case SW:	xwith = r * 0.707; ywith = r2 * 0.707; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += r;
		else if (isleft(hvmode))
			curx -= r;
		else if (isup(hvmode))
			cury += r2;
		else
			cury -= r2;
	}
	p = makenode(type, 2);
	p->o_val[0] = rad[t] = r;
	p->o_val[1] = rad2[t] = r2;
	if (r <= 0 || r2 <= 0) {
		yyerror("%s has invalid radius %g\n", (type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2);
	}
	p->o_attr = invis | ddtype;
	extreme(curx+r, cury+r2);
	extreme(curx-r, cury-r2);
	if (type == CIRCLE)
		dprintf("C %g %g %g\n", curx, cury, r);
	if (type == ELLIPSE)
		dprintf("E %g %g %g %g\n", curx, cury, r, r2);
	if (isright(hvmode))
		curx += r;
	else if (isleft(hvmode))
		curx -= r;
	else if (isup(hvmode))
		cury += r2;
	else
		cury -= r2;
	return(p);
}
コード例 #21
0
ファイル: arcgen.c プロジェクト: PhillipNordwall/original-bsd
obj *arcgen(type)	/* handles circular and (eventually) elliptical arcs */
{
	static float prevw = HT10;
	static float prevh = HT5;
	static float prevrad = HT2;
	static int dtox[2][4] ={ 1, -1, -1, 1, 1, 1, -1, -1 };
	static int dtoy[2][4] ={ 1, 1, -1, -1, -1, 1, 1, -1 };
	static int dctrx[2][4] ={ 0, -1, 0, 1, 0, 1, 0, -1 };
	static int dctry[2][4] ={ 1, 0, -1, 0, -1, 0, 1, 0 };
	static int nexthv[2][4] ={ U_DIR, L_DIR, D_DIR, R_DIR, D_DIR, R_DIR, U_DIR, L_DIR };
	float dx2, dy2, ht, phi, r, d, ddval;
	int i, head, to, at, cw, invis, ddtype;
	obj *p, *ppos;
	float fromx, fromy, tox, toy;
	Attr *ap;

	prevrad = getfval("arcrad");
	prevh = getfval("arrowht");
	prevw = getfval("arrowwid");
	fromx = curx;
	fromy = cury;
	head = to = at = cw = invis = ddtype = 0;
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		case HEAD:
			head += ap->a_val.i;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case DOT:
		case DASH:
			ddtype = ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		case HEIGHT:	/* length of arrowhead */
			prevh = ap->a_val.f;
			break;
		case WIDTH:	/* width of arrowhead */
			prevw = ap->a_val.f;
			break;
		case RADIUS:
			prevrad = ap->a_val.f;
			break;
		case DIAMETER:
			prevrad = ap->a_val.f / 2;
			break;
		case CW:
			cw = 1;
			break;
		case FROM:	/* start point of arc */
			ppos = ap->a_val.o;
			fromx = ppos->o_x;
			fromy = ppos->o_y;
			break;
		case TO:	/* end point of arc */
			ppos = ap->a_val.o;
			tox = ppos->o_x;
			toy = ppos->o_y;
			to++;
			break;
		case AT:	/* center of arc */
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at = 1;
			break;
		case UP:
			hvmode = U_DIR;
			break;
		case DOWN:
			hvmode = D_DIR;
			break;
		case RIGHT:
			hvmode = R_DIR;
			break;
		case LEFT:
			hvmode = L_DIR;
			break;
		}
	}
	if (!at && !to) {	/* the defaults are mostly OK */
		curx = fromx + prevrad * dctrx[cw][hvmode];
		cury = fromy + prevrad * dctry[cw][hvmode];
		tox = fromx + prevrad * dtox[cw][hvmode];
		toy = fromy + prevrad * dtoy[cw][hvmode];
		hvmode = nexthv[cw][hvmode];
	}
	else if (!at) {
		dx2 = (tox - fromx) / 2;
		dy2 = (toy - fromy) / 2;
		phi = atan2(dy2, dx2) + (cw ? -PI/2 : PI/2);
		if (prevrad <= 0.0)
			prevrad = dx2*dx2+dy2*dy2;
		for (r=prevrad; (d = r*r - (dx2*dx2+dy2*dy2)) <= 0.0; r *= 2)
			;	/* this kludge gets around too-small radii */
		prevrad = r;
		ht = sqrt(d);
		curx = fromx + dx2 + ht * cos(phi);
		cury = fromy + dy2 + ht * sin(phi);
		dprintf("dx2,dy2=%g,%g, phi=%g, r,ht=%g,%g\n",
			dx2, dy2, phi, r, ht);
	}
	else if (at && !to) {	/* do we have all the cases??? */
		tox = fromx + prevrad * dtox[cw][hvmode];
		toy = fromy + prevrad * dtoy[cw][hvmode];
		hvmode = nexthv[cw][hvmode];
	}
	if (cw) {	/* interchange roles of from-to and heads */
		float temp;
		temp = fromx; fromx = tox; tox = temp;
		temp = fromy; fromy = toy; toy = temp;
		if (head == HEAD1)
			head = HEAD2;
		else if (head == HEAD2)
			head = HEAD1;
	}
	p = makenode(type, 7);
	arc_extreme(fromx, fromy, tox, toy, curx, cury);
	p->o_val[0] = fromx;
	p->o_val[1] = fromy;
	p->o_val[2] = tox;
	p->o_val[3] = toy;
	if (cw) {
		curx = fromx;
		cury = fromy;
	} else {
		curx = tox;
		cury = toy;
	}
	p->o_val[4] = prevw;
	p->o_val[5] = prevh;
	p->o_val[6] = prevrad;
	p->o_attr = head | (cw ? CW_ARC : 0) | invis | ddtype;
	if (head)
		p->o_nhead = getfval("arrowhead");
	dprintf("arc rad %g at %g %g from %g %g to %g %g head %g %g\n",
		prevrad, p->o_x, p->o_y,
		p->o_val[0], p->o_val[1], p->o_val[2], p->o_val[3], p->o_val[4], p->o_val[5]);
	return(p);
}
コード例 #22
0
ファイル: textgen.c プロジェクト: 00001/plan9port
obj *textgen(void)
{
	int i, sub, nstr, at, with, hset, invis;
	double xwith, ywith, h, w, x0, y0, x1, y1;
	obj *p, *ppos;
	Attr *ap;

	at = with = nstr = hset = invis = 0;
	h = getfval("textht");
	w = getfval("textwid");
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case HEIGHT:
			h = ap->a_val.f;
			hset++;
			break;
		case WIDTH:
			w = ap->a_val.f;
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case INVIS:
			invis = INVIS;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case TEXTATTR:
			sub = ap->a_sub;
			if (ap->a_val.p == NULL)	/* an isolated modifier */
				text[ntext-1].t_type = sub;
			else {
				savetext(sub, ap->a_val.p);
				nstr++;
			}
			break;
		}
	}
	if (hset == 0)		/* no explicit ht cmd */
		h *= nstr;
	if (with) {
		xwith = ywith = 0.0;
		switch (with) {
		case NORTH:	ywith = -h / 2; break;
		case SOUTH:	ywith = h / 2; break;
		case EAST:	xwith = -w / 2; break;
		case WEST:	xwith = w / 2; break;
		case NE:	xwith = -w / 2; ywith = -h / 2; break;
		case SE:	xwith = -w / 2; ywith = h / 2; break;
		case NW:	xwith = w / 2; ywith = -h / 2; break;
		case SW:	xwith = w / 2; ywith = h / 2; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += w / 2;
		else if (isleft(hvmode))
			curx -= w / 2;
		else if (isup(hvmode))
			cury += h / 2;
		else
			cury -= h / 2;
	}
	x0 = curx - w / 2;
	y0 = cury - h / 2;
	x1 = curx + w / 2;
	y1 = cury + h / 2;
	extreme(x0, y0);
	extreme(x1, y1);
	dprintf("Text h %g w %g at %g,%g\n", h, w, curx, cury);
	p = makenode(TEXT, 2);
	p->o_attr = invis;
	p->o_val[0] = w;
	p->o_val[1] = h;
	if (isright(hvmode))
		curx = x1;
	else if (isleft(hvmode))
		curx = x0;
	else if (isup(hvmode))
		cury = y1;
	else
		cury = y0;
	return(p);
}
コード例 #23
0
int format(char **pbuf, int *pbufsize, const char *s, Node *a)	/* printf-like conversions */
{
	char *fmt;
	char *p, *t;
	const char *os;
	Cell *x;
	int flag = 0, n;
	int fmtwd; /* format width */
	int fmtsz = recsize;
	char *buf = *pbuf;
	int bufsize = *pbufsize;

	os = s;
	p = buf;
	if ((fmt = (char *) malloc(fmtsz)) == NULL)
		FATAL("out of memory in format()");
	while (*s) {
		adjbuf(&buf, &bufsize, MAXNUMSIZE+1+p-buf, recsize, &p, "format1");
		if (*s != '%') {
			*p++ = *s++;
			continue;
		}
		if (*(s+1) == '%') {
			*p++ = '%';
			s += 2;
			continue;
		}
		/* have to be real careful in case this is a huge number, eg, %100000d */
		fmtwd = atoi(s+1);
		if (fmtwd < 0)
			fmtwd = -fmtwd;
		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format2");
		for (t = fmt; (*t++ = *s) != '\0'; s++) {
			if (!adjbuf(&fmt, &fmtsz, MAXNUMSIZE+1+t-fmt, recsize, &t, "format3"))
				FATAL("format item %.30s... ran format() out of memory", os);
			if (isalpha((uschar)*s) && *s != 'l' && *s != 'h' && *s != 'L')
				break;	/* the ansi panoply */
			if (*s == '*') {
				x = execute(a);
				a = a->nnext;
				sprintf(t-1, "%d", fmtwd=(int) getfval(x));
				if (fmtwd < 0)
					fmtwd = -fmtwd;
				adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format");
				t = fmt + strlen(fmt);
				tempfree(x);
			}
		}
		*t = '\0';
		if (fmtwd < 0)
			fmtwd = -fmtwd;
		adjbuf(&buf, &bufsize, fmtwd+1+p-buf, recsize, &p, "format4");

		switch (*s) {
		case 'f': case 'e': case 'g': case 'E': case 'G':
			flag = 'f';
			break;
		case 'd': case 'i':
			flag = 'd';
			if(*(s-1) == 'l') break;
			*(t-1) = 'l';
			*t = 'd';
			*++t = '\0';
			break;
		case 'o': case 'x': case 'X': case 'u':
			flag = *(s-1) == 'l' ? 'd' : 'u';
			break;
		case 's':
			flag = 's';
			break;
		case 'c':
			flag = 'c';
			break;
		default:
			WARNING("weird printf conversion %s", fmt);
			flag = '?';
			break;
		}
		if (a == NULL)
			FATAL("not enough args in printf(%s)", os);
		x = execute(a);
		a = a->nnext;
		n = MAXNUMSIZE;
		if (fmtwd > n)
			n = fmtwd;
		adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format5");
		switch (flag) {
		case '?':	sprintf(p, "%s", fmt);	/* unknown, so dump it too */
			t = getsval(x);
			n = strlen(t);
			if (fmtwd > n)
				n = fmtwd;
			adjbuf(&buf, &bufsize, 1+strlen(p)+n+p-buf, recsize, &p, "format6");
			p += strlen(p);
			sprintf(p, "%s", t);
			break;
		case 'f':	sprintf(p, fmt, getfval(x)); break;
		case 'd':	sprintf(p, fmt, (long) getfval(x)); break;
		case 'u':	sprintf(p, fmt, (int) getfval(x)); break;
		case 's':
			t = getsval(x);
			n = strlen(t);
			if (fmtwd > n)
				n = fmtwd;
			if (!adjbuf(&buf, &bufsize, 1+n+p-buf, recsize, &p, "format7"))
				FATAL("huge string/format (%d chars) in printf %.30s... ran format() out of memory", n, t);
			sprintf(p, fmt, t);
			break;
		case 'c':
			if (isnum(x)) {
				if (getfval(x))
					sprintf(p, fmt, (int) getfval(x));
				else {
					*p++ = '\0'; /* explicit null byte */
					*p = '\0';   /* next output will start here */
				}
			} else
				sprintf(p, fmt, getsval(x)[0]);
			break;
		default:
			FATAL("can't happen: bad conversion %c in format()", flag);
		}
		tempfree(x);
		p += strlen(p);
		s++;
	}
	*p = '\0';
	free(fmt);
	for ( ; a; a = a->nnext)		/* evaluate any remaining args */
		execute(a);
	*pbuf = buf;
	*pbufsize = bufsize;
	return p - buf;
}
コード例 #24
0
Cell *bltin(Node **a, int n)	/* builtin functions. a[0] is type, a[1] is arg list */
{
	Cell *x, *y;
	Awkfloat u;
	int t;
	Awkfloat tmp;
	char *p, *buf;
	Node *nextarg;
	FILE *fp;
	void flush_all(void);

	t = ptoi(a[0]);
	x = execute(a[1]);
	nextarg = a[1]->nnext;
	switch (t) {
	case FLENGTH:
		if (isarr(x))
			u = ((Array *) x->sval)->nelem;	/* GROT.  should be function*/
		else
			u = strlen(getsval(x));
		break;
	case FLOG:
		u = errcheck(log(getfval(x)), "log"); break;
	case FINT:
		modf(getfval(x), &u); break;
	case FEXP:
		u = errcheck(exp(getfval(x)), "exp"); break;
	case FSQRT:
		u = errcheck(sqrt(getfval(x)), "sqrt"); break;
	case FSIN:
		u = sin(getfval(x)); break;
	case FCOS:
		u = cos(getfval(x)); break;
	case FATAN:
		if (nextarg == 0) {
			WARNING("atan2 requires two arguments; returning 1.0");
			u = 1.0;
		} else {
			y = execute(a[1]->nnext);
			u = atan2(getfval(x), getfval(y));
			tempfree(y);
			nextarg = nextarg->nnext;
		}
		break;
	case FSYSTEM:
		fflush(stdout);		/* in case something is buffered already */
		u = (Awkfloat) system(getsval(x)) / 256;   /* 256 is unix-dep */
		break;
	case FRAND:
		/* in principle, rand() returns something in 0..RAND_MAX */
		u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX;
		break;
	case FSRAND:
		if (isrec(x))	/* no argument provided */
			u = time((time_t *)0);
		else
			u = getfval(x);
		tmp = u;
		srand((unsigned int) u);
		u = srand_seed;
		srand_seed = tmp;
		break;
	case FTOUPPER:
	case FTOLOWER:
		buf = tostring(getsval(x));
		if (t == FTOUPPER) {
			for (p = buf; *p; p++)
				if (islower((uschar) *p))
					*p = toupper((uschar)*p);
		} else {
			for (p = buf; *p; p++)
				if (isupper((uschar) *p))
					*p = tolower((uschar)*p);
		}
		tempfree(x);
		x = gettemp();
		setsval(x, buf);
		free(buf);
		return x;
	case FFLUSH:
		if (isrec(x) || strlen(getsval(x)) == 0) {
			flush_all();	/* fflush() or fflush("") -> all */
			u = 0;
		} else if ((fp = openfile(FFLUSH, getsval(x))) == NULL)
			u = EOF;
		else
			u = fflush(fp);
		break;
	default:	/* can't happen */
		FATAL("illegal function type %d", t);
		break;
	}
	tempfree(x);
	x = gettemp();
	setfval(x, u);
	if (nextarg != 0) {
		WARNING("warning: function has too many arguments");
		for ( ; nextarg; nextarg = nextarg->nnext)
			execute(nextarg);
	}
	return(x);
}
コード例 #25
0
ファイル: movegen.c プロジェクト: 00001/plan9port
obj*
movegen(void)
{
	static double prevdx, prevdy;
	int i, some;
	double defx, defy, dx, dy;
	obj *p;
	obj *ppos;
	static int xtab[] = { 1, 0, -1, 0 };	/* R=0, U=1, L=2, D=3 */
	static int ytab[] = { 0, 1, 0, -1 };
	Attr *ap;

	defx = getfval("movewid");
	defy = getfval("moveht");
	dx = dy = some = 0;
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		case SAME:
			dx = prevdx;
			dy = prevdy;
			some++;
			break;
		case LEFT:
			dx -= (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
			some++;
			hvmode = L_DIR;
			break;
		case RIGHT:
			dx += (ap->a_sub==DEFAULT) ? defx : ap->a_val.f;
			some++;
			hvmode = R_DIR;
			break;
		case UP:
			dy += (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
			some++;
			hvmode = U_DIR;
			break;
		case DOWN:
			dy -= (ap->a_sub==DEFAULT) ? defy : ap->a_val.f;
			some++;
			hvmode = D_DIR;
			break;
		case TO:
			ppos = ap->a_val.o;
			dx = ppos->o_x - curx;
			dy = ppos->o_y - cury;
			some++;
			break;
		case BY:
			ppos = ap->a_val.o;
			dx = ppos->o_x;
			dy = ppos->o_y;
			some++;
			break;
		case FROM:
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			break;
		}
	}
	if (some) {
		defx = dx;
		defy = dy;
	} else {
		defx *= xtab[hvmode];
		defy *= ytab[hvmode];
	}
	prevdx = defx;
	prevdy = defy;
	extreme(curx, cury);
	curx += defx;
	cury += defy;
	extreme(curx, cury);
	p = makenode(MOVE, 0);
	dprintf("M %g %g\n", curx, cury);
	return(p);
}
コード例 #26
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *assign(Node **a, int n)	/* a[0] = a[1], a[0] += a[1], etc. */
{		/* this is subtle; don't muck with it. */
	Cell *x, *y;
	Awkfloat xf, yf;
	double v;

	y = execute(a[1]);
	x = execute(a[0]);
	if (n == ASSIGN) {	/* ordinary assignment */
		if (x == y && !(x->tval & (FLD|REC)))	/* self-assignment: */
			;		/* leave alone unless it's a field */
		else if ((y->tval & (STR|NUM)) == (STR|NUM)) {
			setsval(x, getsval(y));
			x->fval = getfval(y);
			x->tval |= NUM;
		}
		else if (y->tval & STR)
			setsval(x, getsval(y));
		else if (y->tval & NUM)
			setfval(x, getfval(y));
		else
			funnyvar(y, "read value of");
		tempfree(y);
		return(x);
	}
	xf = getfval(x);
	yf = getfval(y);
	switch (n) {
	case ADDEQ:
		xf += yf;
		break;
	case SUBEQ:
		xf -= yf;
		break;
	case MULTEQ:
		xf *= yf;
		break;
	case DIVEQ:
		if (yf == 0)
			ERROR "division by zero in /=" FATAL;
		xf /= yf;
		break;
	case MODEQ:
		if (yf == 0)
			ERROR "division by zero in %%=" FATAL;
		modf(xf/yf, &v);
		xf = xf - yf * v;
		break;
	case POWEQ:
		if (yf >= 0 && modf(yf, &v) == 0.0)	/* pos integer exponent */
			xf = ipow(xf, (int) yf);
		else
			xf = errcheck(pow(xf, yf), "pow");
		break;
	default:
		ERROR "illegal assignment operator %d", n FATAL;
		break;
	}
	tempfree(y);
	setfval(x, xf);
	return(x);
}
コード例 #27
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
Cell *bltin(Node **a, int n)	/* builtin functions. a[0] is type, a[1] is arg list */
{
	register Cell *x, *y;
	Awkfloat u;
	register int t;
	uchar *p, buf[RECSIZE];
	Node *nextarg;
	FILE *fp;

	t = (int) a[0];
	x = execute(a[1]);
	nextarg = a[1]->nnext;
	switch (t) {
	case FLENGTH:
		u = strlen(getsval(x)); break;
	case FLOG:
		u = errcheck(log(getfval(x)), "log"); break;
	case FINT:
		modf(getfval(x), &u); break;
	case FEXP:
		u = errcheck(exp(getfval(x)), "exp"); break;
	case FSQRT:
		u = errcheck(sqrt(getfval(x)), "sqrt"); break;
	case FSIN:
		u = sin(getfval(x)); break;
	case FCOS:
		u = cos(getfval(x)); break;
	case FATAN:
		if (nextarg == 0) {
			ERROR "atan2 requires two arguments; returning 1.0" WARNING;
			u = 1.0;
		} else {
			y = execute(a[1]->nnext);
			u = atan2(getfval(x), getfval(y));
			tempfree(y);
			nextarg = nextarg->nnext;
		}
		break;
	case FSYSTEM:
		fflush(stdout);		/* in case something is buffered already */
		u = (Awkfloat) system((char *)getsval(x)) / 256;   /* 256 is unix-dep */
		break;
	case FRAND:
		/* in principle, rand() returns something in 0..RAND_MAX */
		u = (Awkfloat) (rand() % RAND_MAX) / RAND_MAX;
		break;
	case FSRAND:
		if (x->tval & REC)	/* no argument provided */
			u = time((long *)0);
		else
			u = getfval(x);
		srand((int) u); u = (int) u;
		break;
	case FTOUPPER:
	case FTOLOWER:
		strcpy(buf, getsval(x));
		if (t == FTOUPPER) {
			for (p = buf; *p; p++)
				if (islower(*p))
					*p = toupper(*p);
		} else {
			for (p = buf; *p; p++)
				if (isupper(*p))
					*p = tolower(*p);
		}
		tempfree(x);
		x = gettemp();
		setsval(x, buf);
		return x;
	case FFLUSH:
		if ((fp = openfile(GT, getsval(x))) == NULL)
			u = EOF;
		else
			u = fflush(fp);
		break;
	default:	/* can't happen */
		ERROR "illegal function type %d", t FATAL;
		break;
	}
	tempfree(x);
	x = gettemp();
	setfval(x, u);
	if (nextarg != 0) {
		ERROR "warning: function has too many arguments" WARNING;
		for ( ; nextarg; nextarg = nextarg->nnext)
			execute(nextarg);
	}
	return(x);
}
コード例 #28
0
ファイル: circgen.c プロジェクト: n-t-roff/DWB3.3
obj *
circgen(int type) {
static	double	rad[2]	= { HT2, WID2 };
static	double	rad2[2]	= { HT2, HT2 };

struct	objattr	obat;
	double	xwith, ywith, r, r2;
	int	i, at, t, with;
	obj	*p, *ppos;
	Attr	*ap;

	obat.a_layer = (int)getfval("curlayer");
	obat.a_flags = EDGED;
	obat.a_weight = obat.a_lcolor = obat.a_pcolor = obat.a_tcolor = -1;
	obat.a_dashpat.a = (float *)0;
	at = with = xwith = ywith = 0;
	if ((t = (type == CIRCLE) ? 0 : 1)) {
		r = getfval("ellipsewid") / 2;
		r2 = getfval("ellipseht") / 2;
	}
	else
		r = r2 = getfval("circlerad");
	set_text();
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		default:
			miscattrs(ap, &obat);
			break;
		case RADIUS:
			r = ap->a_val.f;
			break;
		case DIAMETER:
		case WIDTH:
			r = ap->a_val.f / 2;
			break;
		case HEIGHT:
			r2 = ap->a_val.f / 2;
			break;
		case SAME:
			r = rad[t];
			r2 = rad2[t];
			break;
		case WITH:
			with = ap->a_val.i;
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = Xformx(ppos, 1, ppos->o_x, ppos->o_y);
			cury = Xformy(ppos, 0, ppos->o_x, ppos->o_y);
			at++;
			break;
		}
	}
	if (type == CIRCLE)
		r2 = r;	/* probably superfluous */
	if (with) {
		if (pic_compat)		/* map NE to 2nd, etc. */
			with =	with == NE ? 2 :
				with == NW ? 4 :
				with == SW ? 6 :
				with == SE ? 8 : with;
		switch (with) {
		case NORTH:	ywith = -r2;			break;
		case SOUTH:	ywith = r2;			break;
		case EAST:	xwith = -r;			break;
		case WEST:	xwith = r;			break;
		case NE:	xwith = -r;	ywith = -r2;	break;
		case SE:	xwith = -r;	ywith =  r2;	break;
		case NW:	xwith =  r;	ywith = -r2;	break;
		case SW:	xwith =  r;	ywith =  r2;	break;
		case CENTER:
		case START:
		case END:					break;
		default:	xwith =  -r * xdelta[with % 8];
				ywith = -r2 * ydelta[with % 8];
				if (with % 2 == 0) {
					xwith *= M_SQRT1_2;
					ywith *= M_SQRT1_2;
				}
				break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += r;
		else if (isleft(hvmode))
			curx -= r;
		else if (isup(hvmode))
			cury += r2;
		else
			cury -= r2;
	}
	if (r <= 0 || r2 <= 0)
		yyerror("%s has invalid radius %g",
			(type==CIRCLE) ? "circle" : "ellipse", r<r2 ? r : r2);
	p = makenode(type, N_VAL, obat.a_layer);
	p->o_wid = 2 * (rad[t]  = r);
	p->o_ht  = 2 * (rad2[t] = r2);
	primattrs(p, &obat);
	text_bounds(p);
	if (isright(hvmode))
		curx += r;
	else if (isleft(hvmode))
		curx -= r;
	else if (isup(hvmode))
		cury += r2;
	else
		cury -= r2;
	r  += p->o_weight/2;
	r2 += p->o_weight/2;
	track_bounds (p->o_x - r, p->o_y - r2, p->o_x + r, p->o_y + r2);
	return(p);
}
コード例 #29
0
ファイル: boxgen.c プロジェクト: 99years/plan9
obj *boxgen(void)
{
	static double prevh = HT;
	static double prevw = WID;	/* golden mean, sort of */
	int i, at, battr, with;
	double ddval, fillval, xwith, ywith;
	double h, w, x0, y0, x1, y1;
	obj *p, *ppos;
	Attr *ap;

	h = getfval("boxht");
	w = getfval("boxwid");
	at = battr = with = 0;
	ddval = fillval = xwith = ywith = 0;
	for (i = 0; i < nattr; i++) {
		ap = &attr[i];
		switch (ap->a_type) {
		case HEIGHT:
			h = ap->a_val.f;
			break;
		case WIDTH:
			w = ap->a_val.f;
			break;
		case SAME:
			h = prevh;
			w = prevw;
			break;
		case WITH:
			with = ap->a_val.i;	/* corner */
			break;
		case AT:
			ppos = ap->a_val.o;
			curx = ppos->o_x;
			cury = ppos->o_y;
			at++;
			break;
		case INVIS:
			battr |= INVIS;
			break;
		case NOEDGE:
			battr |= NOEDGEBIT;
			break;
		case DOT:
		case DASH:
			battr |= ap->a_type==DOT ? DOTBIT : DASHBIT;
			if (ap->a_sub == DEFAULT)
				ddval = getfval("dashwid");
			else
				ddval = ap->a_val.f;
			break;
		case FILL:
			battr |= FILLBIT;
			if (ap->a_sub == DEFAULT)
				fillval = getfval("fillval");
			else
				fillval = ap->a_val.f;
			break;
		case TEXTATTR:
			savetext(ap->a_sub, ap->a_val.p);
			break;
		}
	}
	if (with) {
		switch (with) {
		case NORTH:	ywith = -h / 2; break;
		case SOUTH:	ywith = h / 2; break;
		case EAST:	xwith = -w / 2; break;
		case WEST:	xwith = w / 2; break;
		case NE:	xwith = -w / 2; ywith = -h / 2; break;
		case SE:	xwith = -w / 2; ywith = h / 2; break;
		case NW:	xwith = w / 2; ywith = -h / 2; break;
		case SW:	xwith = w / 2; ywith = h / 2; break;
		}
		curx += xwith;
		cury += ywith;
	}
	if (!at) {
		if (isright(hvmode))
			curx += w / 2;
		else if (isleft(hvmode))
			curx -= w / 2;
		else if (isup(hvmode))
			cury += h / 2;
		else
			cury -= h / 2;
	}
	x0 = curx - w / 2;
	y0 = cury - h / 2;
	x1 = curx + w / 2;
	y1 = cury + h / 2;
	extreme(x0, y0);
	extreme(x1, y1);
	p = makenode(BOX, 2);
	p->o_val[0] = w;
	p->o_val[1] = h;
	p->o_attr = battr;
	p->o_ddval = ddval;
	p->o_fillval = fillval;
	dprintf("B %g %g %g %g at %g %g, h=%g, w=%g\n", x0, y0, x1, y1, curx, cury, h, w);
	if (isright(hvmode))
		curx = x1;
	else if (isleft(hvmode))
		curx = x0;
	else if (isup(hvmode))
		cury = y1;
	else
		cury = y0;
	prevh = h;
	prevw = w;
	return(p);
}
コード例 #30
0
ファイル: run.c プロジェクト: ajallooeian/libawkcpp
int format(char *buf, int bufsize, char *s, Node *a)	/* printf-like conversions */
{
	char fmt[RECSIZE];
	char *p, *t, *os;
	Cell *x;
	int flag = 0, n;

	os = s;
	p = buf;
	while (*s) {
		if (p - buf >= bufsize)
			return -1;
		if (*s != '%') {
			*p++ = *s++;
			continue;
		}
		if (*(s+1) == '%') {
			*p++ = '%';
			s += 2;
			continue;
		}
		for (t=fmt; (*t++ = *s) != '\0'; s++) {
			if (isalpha(*s) && *s != 'l' && *s != 'h' && *s != 'L')
				break;	/* the ansi panoply */
			if (*s == '*') {
				x = execute(a);
				a = a->nnext;
				sprintf((char *)t-1, "%d", (int) getfval(x));
				t = fmt + strlen(fmt);
				tempfree(x);
			}
		}
		*t = '\0';
		if (t >= fmt + sizeof(fmt))
			ERROR "format item %.30s... too long", os FATAL;
		switch (*s) {
		case 'f': case 'e': case 'g': case 'E': case 'G':
			flag = 1;
			break;
		case 'd': case 'i':
			flag = 2;
			if(*(s-1) == 'l') break;
			*(t-1) = 'l';
			*t = 'd';
			*++t = '\0';
			break;
		case 'o': case 'x': case 'X': case 'u':
			flag = *(s-1) == 'l' ? 2 : 3;
			break;
		case 's':
			flag = 4;
			break;
		case 'c':
			flag = 5;
			break;
		default:
			ERROR "weird printf conversion %s", fmt WARNING;
			flag = 0;
			break;
		}
		if (a == NULL)
			ERROR "not enough args in printf(%s)", os FATAL;
		x = execute(a);
		a = a->nnext;
		switch (flag) {
		case 0:	sprintf((char *)p, "%s", fmt);	/* unknown, so dump it too */
			p += strlen(p);
			sprintf((char *)p, "%s", getsval(x));
			break;
		case 1:	sprintf((char *)p, (char *)fmt, getfval(x)); break;
		case 2:	sprintf((char *)p, (char *)fmt, (long) getfval(x)); break;
		case 3:	sprintf((char *)p, (char *)fmt, (int) getfval(x)); break;
		case 4:
			t = getsval(x);
			n = strlen(t);
			if (n >= bufsize)
				ERROR "huge string (%d chars) in printf %.30s...",
					n, t FATAL;
			sprintf((char *)p, (char *)fmt, t);
			break;
		case 5:
			isnum(x) ? sprintf((char *)p, (char *)fmt, (int) getfval(x))
				 : sprintf((char *)p, (char *)fmt, getsval(x)[0]);
			break;
		}
		tempfree(x);
		p += strlen(p);
		s++;
	}
	*p = '\0';
	for ( ; a; a = a->nnext)		/* evaluate any remaining args */
		execute(a);
	return 0;
}