| 1 | #include <stdio.h> |
| 2 | #include <ctype.h> |
| 3 | #include <math.h> |
| 4 | #define INF 1.e+37 |
| 5 | #define F .25 |
| 6 | |
| 7 | struct xy { |
| 8 | int xlbf; /*flag:explicit lower bound*/ |
| 9 | int xubf; /*flag:explicit upper bound*/ |
| 10 | int xqf; /*flag:explicit quantum*/ |
| 11 | double (*xf)(); /*transform function, e.g. log*/ |
| 12 | float xa,xb; /*scaling coefficients*/ |
| 13 | float xlb,xub; /*lower and upper bound*/ |
| 14 | float xquant; /*quantum*/ |
| 15 | float xoff; /*screen offset fraction*/ |
| 16 | float xsize; /*screen fraction*/ |
| 17 | int xbot,xtop; /*screen coords of border*/ |
| 18 | float xmult; /*scaling constant*/ |
| 19 | } xd,yd; |
| 20 | struct val { |
| 21 | float xv; |
| 22 | float yv; |
| 23 | int lblptr; |
| 24 | } *xx; |
| 25 | |
| 26 | char *labs; |
| 27 | int labsiz; |
| 28 | |
| 29 | int tick = 50; |
| 30 | int top = 4000; |
| 31 | int bot = 200; |
| 32 | float absbot; |
| 33 | int n; |
| 34 | int erasf = 1; |
| 35 | int gridf = 2; |
| 36 | int symbf = 0; |
| 37 | int absf = 0; |
| 38 | int transf; |
| 39 | int brkf; |
| 40 | float dx; |
| 41 | char *plotsymb; |
| 42 | |
| 43 | double atof(); |
| 44 | #define BSIZ 80 |
| 45 | char labbuf[BSIZ]; |
| 46 | char titlebuf[BSIZ]; |
| 47 | |
| 48 | char *modes[] = { |
| 49 | "disconnected", |
| 50 | "solid", |
| 51 | "dotted", |
| 52 | "dotdashed", |
| 53 | "shortdashed", |
| 54 | "longdashed" |
| 55 | }; |
| 56 | int mode = 1; |
| 57 | char *realloc(); |
| 58 | char *malloc(); |
| 59 | |
| 60 | double ident(x) |
| 61 | double x; |
| 62 | { |
| 63 | return(x); |
| 64 | } |
| 65 | |
| 66 | main(argc,argv) |
| 67 | char *argv[]; |
| 68 | { |
| 69 | |
| 70 | space(0,0,4096,4096); |
| 71 | init(&xd); |
| 72 | init(&yd); |
| 73 | xd.xsize = yd.xsize = 1.; |
| 74 | xx = (struct val *)malloc((unsigned)sizeof(struct val)); |
| 75 | labs = malloc(1); |
| 76 | labs[labsiz++] = 0; |
| 77 | setopt(argc,argv); |
| 78 | if(erasf) |
| 79 | erase(); |
| 80 | readin(); |
| 81 | transpose(); |
| 82 | scale(&xd,(struct val *)&xx->xv); |
| 83 | scale(&yd,(struct val *)&xx->yv); |
| 84 | axes(); |
| 85 | title(); |
| 86 | plot(); |
| 87 | move(1,1); |
| 88 | closevt(); |
| 89 | return(0); |
| 90 | } |
| 91 | |
| 92 | init(p) |
| 93 | struct xy *p; |
| 94 | { |
| 95 | p->xf = ident; |
| 96 | p->xmult = 1; |
| 97 | } |
| 98 | |
| 99 | setopt(argc,argv) |
| 100 | char *argv[]; |
| 101 | { |
| 102 | char *p1, *p2; |
| 103 | float temp; |
| 104 | |
| 105 | xd.xlb = yd.xlb = INF; |
| 106 | xd.xub = yd.xub = -INF; |
| 107 | while(--argc > 0) { |
| 108 | argv++; |
| 109 | again: switch(argv[0][0]) { |
| 110 | case '-': |
| 111 | argv[0]++; |
| 112 | goto again; |
| 113 | case 'l': /* label for plot */ |
| 114 | p1 = titlebuf; |
| 115 | if (argc>=2) { |
| 116 | argv++; |
| 117 | argc--; |
| 118 | p2 = argv[0]; |
| 119 | while (*p1++ = *p2++); |
| 120 | } |
| 121 | break; |
| 122 | |
| 123 | case 'd': /*disconnected,obsolete option*/ |
| 124 | case 'm': /*line mode*/ |
| 125 | mode = 0; |
| 126 | if(!numb(&temp,&argc,&argv)) |
| 127 | break; |
| 128 | if(temp>=sizeof(modes)/sizeof(*modes)) |
| 129 | mode = 1; |
| 130 | else if(temp>=0) |
| 131 | mode = temp; |
| 132 | break; |
| 133 | |
| 134 | case 'a': /*automatic abscissas*/ |
| 135 | absf = 1; |
| 136 | dx = 1; |
| 137 | if(!numb(&dx,&argc,&argv)) |
| 138 | break; |
| 139 | if(numb(&absbot,&argc,&argv)) |
| 140 | absf = 2; |
| 141 | break; |
| 142 | |
| 143 | case 's': /*save screen, overlay plot*/ |
| 144 | erasf = 0; |
| 145 | break; |
| 146 | |
| 147 | case 'g': /*grid style 0 none, 1 ticks, 2 full*/ |
| 148 | gridf = 0; |
| 149 | if(!numb(&temp,&argc,&argv)) |
| 150 | temp = argv[0][1]-'0'; /*for caompatibility*/ |
| 151 | if(temp>=0&&temp<=2) |
| 152 | gridf = temp; |
| 153 | break; |
| 154 | |
| 155 | case 'c': /*character(s) for plotting*/ |
| 156 | if(argc >= 2) { |
| 157 | symbf = 1; |
| 158 | plotsymb = argv[1]; |
| 159 | argv++; |
| 160 | argc--; |
| 161 | } |
| 162 | break; |
| 163 | |
| 164 | case 't': /*transpose*/ |
| 165 | transf = 1; |
| 166 | break; |
| 167 | case 'b': /*breaks*/ |
| 168 | brkf = 1; |
| 169 | break; |
| 170 | case 'x': /*x limits */ |
| 171 | limread(&xd,&argc,&argv); |
| 172 | break; |
| 173 | case 'y': |
| 174 | limread(&yd,&argc,&argv); |
| 175 | break; |
| 176 | case 'h': /*set height of plot */ |
| 177 | if(!numb(&yd.xsize, &argc,&argv)) |
| 178 | badarg(); |
| 179 | break; |
| 180 | case 'w': /*set width of plot */ |
| 181 | if(!numb(&xd.xsize, &argc, &argv)) |
| 182 | badarg(); |
| 183 | break; |
| 184 | case 'r': /* set offset to right */ |
| 185 | if(!numb(&xd.xoff, &argc, &argv)) |
| 186 | badarg(); |
| 187 | break; |
| 188 | case 'u': /*set offset up the screen*/ |
| 189 | if(!numb(&yd.xoff,&argc,&argv)) |
| 190 | badarg(); |
| 191 | break; |
| 192 | default: |
| 193 | badarg(); |
| 194 | } |
| 195 | } |
| 196 | } |
| 197 | |
| 198 | limread(p, argcp, argvp) |
| 199 | register struct xy *p; |
| 200 | int *argcp; |
| 201 | char ***argvp; |
| 202 | { |
| 203 | if(*argcp>1 && (*argvp)[1][0]=='l') { |
| 204 | (*argcp)--; |
| 205 | (*argvp)++; |
| 206 | p->xf = log10; |
| 207 | } |
| 208 | if(!numb(&p->xlb,argcp,argvp)) |
| 209 | return; |
| 210 | p->xlbf = 1; |
| 211 | if(!numb(&p->xub,argcp,argvp)) |
| 212 | return; |
| 213 | p->xubf = 1; |
| 214 | if(!numb(&p->xquant,argcp,argvp)) |
| 215 | return; |
| 216 | p->xqf = 1; |
| 217 | } |
| 218 | |
| 219 | numb(np, argcp, argvp) |
| 220 | int *argcp; |
| 221 | float *np; |
| 222 | register char ***argvp; |
| 223 | { |
| 224 | register char c; |
| 225 | |
| 226 | if(*argcp <= 1) |
| 227 | return(0); |
| 228 | while((c=(*argvp)[1][0]) == '+') |
| 229 | (*argvp)[1]++; |
| 230 | if(!(isdigit(c) || c=='-'&&(*argvp)[1][1]<'A' || c=='.')) |
| 231 | return(0); |
| 232 | *np = atof((*argvp)[1]); |
| 233 | (*argcp)--; |
| 234 | (*argvp)++; |
| 235 | return(1); |
| 236 | } |
| 237 | |
| 238 | readin() |
| 239 | { |
| 240 | register t; |
| 241 | struct val *temp; |
| 242 | |
| 243 | if(absf==1) { |
| 244 | if(xd.xlbf) |
| 245 | absbot = xd.xlb; |
| 246 | else if(xd.xf==log10) |
| 247 | absbot = 1; |
| 248 | } |
| 249 | for(;;) { |
| 250 | temp = (struct val *)realloc((char*)xx, |
| 251 | (unsigned)(n+1)*sizeof(struct val)); |
| 252 | if(temp==0) |
| 253 | return; |
| 254 | xx = temp; |
| 255 | if(absf) |
| 256 | xx[n].xv = n*dx + absbot; |
| 257 | else |
| 258 | if(!getfloat(&xx[n].xv)) |
| 259 | return; |
| 260 | if(!getfloat(&xx[n].yv)) |
| 261 | return; |
| 262 | xx[n].lblptr = -1; |
| 263 | t = getstring(); |
| 264 | if(t>0) |
| 265 | xx[n].lblptr = copystring(t); |
| 266 | n++; |
| 267 | if(t<0) |
| 268 | return; |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | transpose() |
| 273 | { |
| 274 | register i; |
| 275 | float f; |
| 276 | struct xy t; |
| 277 | if(!transf) |
| 278 | return; |
| 279 | t = xd; xd = yd; yd = t; |
| 280 | for(i= 0;i<n;i++) { |
| 281 | f = xx[i].xv; xx[i].xv = xx[i].yv; xx[i].yv = f; |
| 282 | } |
| 283 | } |
| 284 | |
| 285 | copystring(k) |
| 286 | { |
| 287 | register char *temp; |
| 288 | register i; |
| 289 | int q; |
| 290 | |
| 291 | temp = realloc(labs,(unsigned)(labsiz+1+k)); |
| 292 | if(temp==0) |
| 293 | return(0); |
| 294 | labs = temp; |
| 295 | q = labsiz; |
| 296 | for(i=0;i<=k;i++) |
| 297 | labs[labsiz++] = labbuf[i]; |
| 298 | return(q); |
| 299 | } |
| 300 | |
| 301 | float |
| 302 | modceil(f,t) |
| 303 | float f,t; |
| 304 | { |
| 305 | |
| 306 | t = fabs(t); |
| 307 | return(ceil(f/t)*t); |
| 308 | } |
| 309 | |
| 310 | float |
| 311 | modfloor(f,t) |
| 312 | float f,t; |
| 313 | { |
| 314 | t = fabs(t); |
| 315 | return(floor(f/t)*t); |
| 316 | } |
| 317 | |
| 318 | getlim(p,v) |
| 319 | register struct xy *p; |
| 320 | struct val *v; |
| 321 | { |
| 322 | register i; |
| 323 | |
| 324 | i = 0; |
| 325 | do { |
| 326 | if(!p->xlbf && p->xlb>v[i].xv) |
| 327 | p->xlb = v[i].xv; |
| 328 | if(!p->xubf && p->xub<v[i].xv) |
| 329 | p->xub = v[i].xv; |
| 330 | i++; |
| 331 | } while(i < n); |
| 332 | } |
| 333 | |
| 334 | struct z { |
| 335 | float lb,ub,mult,quant; |
| 336 | } setloglim(), setlinlim(); |
| 337 | |
| 338 | setlim(p) |
| 339 | register struct xy *p; |
| 340 | { |
| 341 | float t,delta,sign; |
| 342 | struct z z; |
| 343 | int mark[50]; |
| 344 | float lb,ub; |
| 345 | int lbf,ubf; |
| 346 | |
| 347 | lb = p->xlb; |
| 348 | ub = p->xub; |
| 349 | delta = ub-lb; |
| 350 | if(p->xqf) { |
| 351 | if(delta*p->xquant <=0 ) |
| 352 | badarg(); |
| 353 | return; |
| 354 | } |
| 355 | sign = 1; |
| 356 | lbf = p->xlbf; |
| 357 | ubf = p->xubf; |
| 358 | if(delta < 0) { |
| 359 | sign = -1; |
| 360 | t = lb; |
| 361 | lb = ub; |
| 362 | ub = t; |
| 363 | t = lbf; |
| 364 | lbf = ubf; |
| 365 | ubf = t; |
| 366 | } |
| 367 | else if(delta == 0) { |
| 368 | if(ub > 0) { |
| 369 | ub = 2*ub; |
| 370 | lb = 0; |
| 371 | } |
| 372 | else |
| 373 | if(lb < 0) { |
| 374 | lb = 2*lb; |
| 375 | ub = 0; |
| 376 | } |
| 377 | else { |
| 378 | ub = 1; |
| 379 | lb = -1; |
| 380 | } |
| 381 | } |
| 382 | if(p->xf==log10 && lb>0 && ub>lb) { |
| 383 | z = setloglim(lbf,ubf,lb,ub); |
| 384 | p->xlb = z.lb; |
| 385 | p->xub = z.ub; |
| 386 | p->xmult *= z.mult; |
| 387 | p->xquant = z.quant; |
| 388 | if(setmark(mark,p)<2) { |
| 389 | p->xqf = lbf = ubf = 1; |
| 390 | lb = z.lb; ub = z.ub; |
| 391 | } else |
| 392 | return; |
| 393 | } |
| 394 | z = setlinlim(lbf,ubf,lb,ub); |
| 395 | if(sign > 0) { |
| 396 | p->xlb = z.lb; |
| 397 | p->xub = z.ub; |
| 398 | } else { |
| 399 | p->xlb = z.ub; |
| 400 | p->xub = z.lb; |
| 401 | } |
| 402 | p->xmult *= z.mult; |
| 403 | p->xquant = sign*z.quant; |
| 404 | } |
| 405 | |
| 406 | struct z |
| 407 | setloglim(lbf,ubf,lb,ub) |
| 408 | float lb,ub; |
| 409 | { |
| 410 | float r,s,t; |
| 411 | struct z z; |
| 412 | |
| 413 | for(s=1; lb*s<1; s*=10) ; |
| 414 | lb *= s; |
| 415 | ub *= s; |
| 416 | for(r=1; 10*r<=lb; r*=10) ; |
| 417 | for(t=1; t<ub; t*=10) ; |
| 418 | z.lb = !lbf ? r : lb; |
| 419 | z.ub = !ubf ? t : ub; |
| 420 | if(ub/lb<100) { |
| 421 | if(!lbf) { |
| 422 | if(lb >= 5*z.lb) |
| 423 | z.lb *= 5; |
| 424 | else if(lb >= 2*z.lb) |
| 425 | z.lb *= 2; |
| 426 | } |
| 427 | if(!ubf) { |
| 428 | if(ub*5 <= z.ub) |
| 429 | z.ub /= 5; |
| 430 | else if(ub*2 <= z.ub) |
| 431 | z.ub /= 2; |
| 432 | } |
| 433 | } |
| 434 | z.mult = s; |
| 435 | z.quant = r; |
| 436 | return(z); |
| 437 | } |
| 438 | |
| 439 | struct z |
| 440 | setlinlim(lbf,ubf,xlb,xub) |
| 441 | int lbf,ubf; |
| 442 | float xlb,xub; |
| 443 | { |
| 444 | struct z z; |
| 445 | float r,s,delta; |
| 446 | float ub,lb; |
| 447 | |
| 448 | loop: |
| 449 | ub = xub; |
| 450 | lb = xlb; |
| 451 | delta = ub - lb; |
| 452 | /*scale up by s, a power of 10, so range (delta) exceeds 1*/ |
| 453 | /*find power of 10 quantum, r, such that delta/10<=r<delta*/ |
| 454 | r = s = 1; |
| 455 | while(delta*s < 10) |
| 456 | s *= 10; |
| 457 | delta *= s; |
| 458 | while(10*r < delta) |
| 459 | r *= 10; |
| 460 | lb *= s; |
| 461 | ub *= s; |
| 462 | /*set r=(1,2,5)*10**n so that 3-5 quanta cover range*/ |
| 463 | if(r>=delta/2) |
| 464 | r /= 2; |
| 465 | else if(r<delta/5) |
| 466 | r *= 2; |
| 467 | z.ub = ubf? ub: modceil(ub,r); |
| 468 | z.lb = lbf? lb: modfloor(lb,r); |
| 469 | if(!lbf && z.lb<=r && z.lb>0) { |
| 470 | xlb = 0; |
| 471 | goto loop; |
| 472 | } |
| 473 | else if(!ubf && z.ub>=-r && z.ub<0) { |
| 474 | xub = 0; |
| 475 | goto loop; |
| 476 | } |
| 477 | z.quant = r; |
| 478 | z.mult = s; |
| 479 | return(z); |
| 480 | } |
| 481 | |
| 482 | scale(p,v) |
| 483 | register struct xy *p; |
| 484 | struct val *v; |
| 485 | { |
| 486 | float edge; |
| 487 | |
| 488 | getlim(p,v); |
| 489 | setlim(p); |
| 490 | edge = top-bot; |
| 491 | p->xa = p->xsize*edge/((*p->xf)(p->xub) - (*p->xf)(p->xlb)); |
| 492 | p->xbot = bot + edge*p->xoff; |
| 493 | p->xtop = p->xbot + (top-bot)*p->xsize; |
| 494 | p->xb = p->xbot - (*p->xf)(p->xlb)*p->xa + .5; |
| 495 | } |
| 496 | |
| 497 | axes() |
| 498 | { |
| 499 | register i; |
| 500 | int mark[50]; |
| 501 | int xn, yn; |
| 502 | if(gridf==0) |
| 503 | return; |
| 504 | |
| 505 | line(xd.xbot,yd.xbot,xd.xtop,yd.xbot); |
| 506 | cont(xd.xtop,yd.xtop); |
| 507 | cont(xd.xbot,yd.xtop); |
| 508 | cont(xd.xbot,yd.xbot); |
| 509 | |
| 510 | xn = setmark(mark,&xd); |
| 511 | for(i=0; i<xn; i++) { |
| 512 | if(gridf==2) |
| 513 | line(mark[i],yd.xbot,mark[i],yd.xtop); |
| 514 | if(gridf==1) { |
| 515 | line(mark[i],yd.xbot,mark[i],yd.xbot+tick); |
| 516 | line(mark[i],yd.xtop-tick,mark[i],yd.xtop); |
| 517 | } |
| 518 | } |
| 519 | yn = setmark(mark,&yd); |
| 520 | for(i=0; i<yn; i++) { |
| 521 | if(gridf==2) |
| 522 | line(xd.xbot,mark[i],xd.xtop,mark[i]); |
| 523 | if(gridf==1) { |
| 524 | line(xd.xbot,mark[i],xd.xbot+tick,mark[i]); |
| 525 | line(xd.xtop-tick,mark[i],xd.xtop,mark[i]); |
| 526 | } |
| 527 | } |
| 528 | } |
| 529 | |
| 530 | setmark(xmark,p) |
| 531 | int *xmark; |
| 532 | register struct xy *p; |
| 533 | { |
| 534 | int xn = 0; |
| 535 | float x,xl,xu; |
| 536 | float q; |
| 537 | if(p->xf==log10&&!p->xqf) { |
| 538 | for(x=p->xquant; x<p->xub; x*=10) { |
| 539 | submark(xmark,&xn,x,p); |
| 540 | if(p->xub/p->xlb<=100) { |
| 541 | submark(xmark,&xn,2*x,p); |
| 542 | submark(xmark,&xn,5*x,p); |
| 543 | } |
| 544 | } |
| 545 | } else { |
| 546 | xn = 0; |
| 547 | q = p->xquant; |
| 548 | if(q>0) { |
| 549 | xl = modceil(p->xlb+q/6,q); |
| 550 | xu = modfloor(p->xub-q/6,q)+q/2; |
| 551 | } else { |
| 552 | xl = modceil(p->xub-q/6,q); |
| 553 | xu = modfloor(p->xlb+q/6,q)-q/2; |
| 554 | } |
| 555 | for(x=xl; x<=xu; x+=fabs(p->xquant)) |
| 556 | xmark[xn++] = (*p->xf)(x)*p->xa + p->xb; |
| 557 | } |
| 558 | return(xn); |
| 559 | } |
| 560 | submark(xmark,pxn,x,p) |
| 561 | int *xmark; |
| 562 | int *pxn; |
| 563 | float x; |
| 564 | struct xy *p; |
| 565 | { |
| 566 | if(1.001*p->xlb < x && .999*p->xub > x) |
| 567 | xmark[(*pxn)++] = log10(x)*p->xa + p->xb; |
| 568 | } |
| 569 | |
| 570 | plot() |
| 571 | { |
| 572 | int ix,iy; |
| 573 | int i; |
| 574 | int conn; |
| 575 | |
| 576 | conn = 0; |
| 577 | if(mode!=0) |
| 578 | linemod(modes[mode]); |
| 579 | for(i=0; i<n; i++) { |
| 580 | if(!conv(xx[i].xv,&xd,&ix) || |
| 581 | !conv(xx[i].yv,&yd,&iy)) { |
| 582 | conn = 0; |
| 583 | continue; |
| 584 | } |
| 585 | if(mode!=0) { |
| 586 | if(conn != 0) |
| 587 | cont(ix,iy); |
| 588 | else |
| 589 | move(ix,iy); |
| 590 | conn = 1; |
| 591 | } |
| 592 | conn &= symbol(ix,iy,xx[i].lblptr); |
| 593 | } |
| 594 | linemod(modes[1]); |
| 595 | } |
| 596 | |
| 597 | conv(xv,p,ip) |
| 598 | float xv; |
| 599 | register struct xy *p; |
| 600 | int *ip; |
| 601 | { |
| 602 | long ix; |
| 603 | ix = p->xa*(*p->xf)(xv*p->xmult) + p->xb; |
| 604 | if(ix<p->xbot || ix>p->xtop) |
| 605 | return(0); |
| 606 | *ip = ix; |
| 607 | return(1); |
| 608 | } |
| 609 | |
| 610 | getfloat(p) |
| 611 | float *p; |
| 612 | { |
| 613 | register i; |
| 614 | |
| 615 | i = scanf("%f",p); |
| 616 | return(i==1); |
| 617 | } |
| 618 | |
| 619 | getstring() |
| 620 | { |
| 621 | register i; |
| 622 | char junk[20]; |
| 623 | i = scanf("%1s",labbuf); |
| 624 | if(i==-1) |
| 625 | return(-1); |
| 626 | switch(*labbuf) { |
| 627 | default: |
| 628 | if(!isdigit(*labbuf)) { |
| 629 | ungetc(*labbuf,stdin); |
| 630 | i = scanf("%s",labbuf); |
| 631 | break; |
| 632 | } |
| 633 | case '.': |
| 634 | case '+': |
| 635 | case '-': |
| 636 | ungetc(*labbuf,stdin); |
| 637 | return(0); |
| 638 | case '"': |
| 639 | i = scanf("%[^\"\n]",labbuf); |
| 640 | scanf("%[\"]",junk); |
| 641 | break; |
| 642 | } |
| 643 | if(i==-1) |
| 644 | return(-1); |
| 645 | return(strlen(labbuf)); |
| 646 | } |
| 647 | |
| 648 | |
| 649 | symbol(ix,iy,k) |
| 650 | { |
| 651 | |
| 652 | if(symbf==0&&k<0) { |
| 653 | if(mode==0) |
| 654 | point(ix,iy); |
| 655 | return(1); |
| 656 | } |
| 657 | else { |
| 658 | move(ix,iy); |
| 659 | label(k>=0?labs+k:plotsymb); |
| 660 | move(ix,iy); |
| 661 | return(!brkf|k<0); |
| 662 | } |
| 663 | } |
| 664 | |
| 665 | title() |
| 666 | { |
| 667 | move(xd.xbot,yd.xbot-60); |
| 668 | if (titlebuf[0]) { |
| 669 | label(titlebuf); |
| 670 | label(" "); |
| 671 | } |
| 672 | if(erasf&&gridf) { |
| 673 | axlab('x',&xd); |
| 674 | label(" "); |
| 675 | axlab('y',&yd); |
| 676 | } |
| 677 | } |
| 678 | |
| 679 | axlab(c,p) |
| 680 | char c; |
| 681 | struct xy *p; |
| 682 | { |
| 683 | char buf[50]; |
| 684 | sprintf(buf,"%g -%s%c- %g", p->xlb/p->xmult, |
| 685 | p->xf==log10?"log ":"", c, p->xub/p->xmult); |
| 686 | label(buf); |
| 687 | } |
| 688 | |
| 689 | badarg() |
| 690 | { |
| 691 | fprintf(stderr,"graph: error in arguments\n"); |
| 692 | exit(1); |
| 693 | } |