home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / pc / source / fchart.lzh / fchart.4 < prev    next >
Encoding:
Text File  |  1990-06-09  |  42.3 KB  |  1,580 lines

  1.  
  2. #!/bin/sh
  3. # This is part 04 of Fchart
  4. if touch 2>&1 | fgrep '[-amc]' > /dev/null
  5.  then TOUCH=touch
  6.  else TOUCH=true
  7. fi
  8. # ============= fstyles.i ==============
  9. echo "x - extracting fstyles.i (Text)"
  10. sed 's/^X//' << 'SHAR_EOF' > fstyles.i &&
  11. X/* Fchart -- fstyles.i
  12. X *
  13. X * Scratch file containing old version of styles implementation.
  14. X * Unfortunately, I had neither time nor energy to finish writing
  15. X * the second version of it. Maybe later.
  16. X *
  17. X * Modifying this file is not allowed or granted.
  18. X *
  19. X * Copyright (C) 1990 Piotr Filip Sawicki
  20. X *
  21. X * Don't modify this code: throw it away "as is" !
  22. X *
  23. X */
  24. X
  25. Xstruct sqrdim{
  26. X    int numxsqrs;
  27. X    int numysqrs;
  28. X};
  29. X
  30. Xstruct sqrdim *dividesquares(xlen, ylen, numbox)
  31. Xint xlen, ylen, numbox;
  32. X/* find the best pie box layout for given screen. not optimal. sniff :-(
  33. X   write better one, if you can and have any idea how to do that */
  34. X{
  35. X    long i, j;    /* sometimes go very high */
  36. X    static struct sqrdim ST;
  37. X
  38. X    for (i=1; i<=numbox; i++)
  39. X        for (j=numbox/i; j<=numbox; j++)
  40. X            if (i*j>=numbox && 5*ylen/i*j>=xlen && 3*ylen/i*j/2<=xlen)
  41. X                goto found;
  42. X
  43. X    int_error("Division not found. Please inform author: fs@uwasa.fi", NO_CARET);
  44. X    
  45. Xfound:
  46. X    /* first check for boundary conditions */
  47. X    if ((i-1)*j >= numbox)
  48. X        i--;
  49. X    else if ((j-1)*i >= numbox)
  50. X        j--;
  51. X    ST.numxsqrs = j;
  52. X    ST.numysqrs = i;
  53. X    return(&ST);
  54. X}
  55. X
  56. Xdr_pies(xplot)
  57. XBOOLEAN xplot; 
  58. X/* draw piecharts */
  59. X{
  60. X    int x, y, i, j, k = 0, ax, ay, b_i, b_j, b_n;
  61. X    int incr = (p_clockwise ? -1 : 1);
  62. X    double all, st_an, angl, HLangle, vprev, lastang;
  63. X    int box_x, box_y, base_rad, radius;
  64. X    struct chunk *chn, *chnHL;
  65. X    struct dfile *f;
  66. X    vreal *HL_me = NULL, *bound;
  67. X    int numHL = -1;
  68. X    double radrad = (radexp>1.0 ? radexp/100.0 : radexp);
  69. X    double trash = (treshold>1.0 ? treshold/100.0 : treshold);
  70. X    BOOLEAN do_lab = data_head.labels;
  71. X    double treshed = 0.0;    /* anything tresholded ? */
  72. X    char nlab[250], *lblpt;
  73. X    struct sqrdim CX, *divided = &CX;
  74. X
  75. X    if (xplot)
  76. X        return(0);
  77. X
  78. X    box_x = xmaxp - xbase;
  79. X    box_y = ymaxp - ybase;
  80. X    if (data_head.chunks == 1) {
  81. X        divided->numxsqrs = 1;
  82. X        divided->numysqrs = 1;
  83. X    }
  84. X    else {
  85. X        divided = dividesquares(box_x, box_y, data_head.chunks);
  86. X        box_x /= divided->numxsqrs;
  87. X        box_y /= divided->numysqrs;
  88. X    }
  89. X
  90. X    if (box_x < box_y) base_rad = (int) (box_x/2*MARGIN);
  91. X    else base_rad = (int) (box_y/2*MARGIN);
  92. X    /* reserve space for labels - at least 5 chars */
  93. X    if (box_y - base_rad*2 < t->v_char*3)
  94. X        base_rad += box_y - base_rad*2 - t->v_char*3;    /* <0, so OK */
  95. X    if (base_rad<=0)
  96. X        return(0);
  97. X    i = (data_head.chunks != 1);
  98. X    if (box_x - base_rad*2 < t->h_char*(10+i*5))
  99. X        base_rad += box_x - base_rad*2 - t->h_char*(10+i*5);    /* <0, so OK */
  100. X
  101. X    if (base_rad<=0)
  102. X        return(0);
  103. X
  104. X    b_n = divided->numxsqrs * divided->numysqrs;
  105. X    b_j = divided->numysqrs - 1;
  106. X    b_i = 0;
  107. X    (*t->linetype)(0);        /* one type. looks better for piecharts */
  108. X
  109. X    /* main loop with "double engine" */
  110. X    for (f=data_head.dnxt; b_n--; (++b_i == divided->numxsqrs ? b_i=0, --b_j : 1)) {
  111. X        if (b_n >= data_head.chunks)
  112. X            continue;    /* leave topmost boxes empty */
  113. X        
  114. X        x = box_x/2 + xbase + b_i*box_x;
  115. X        y = box_y/2 + ybase + b_j*box_y;
  116. X        
  117. X        chn = f->data;
  118. X        i = j = 0;
  119. X        all = vprev = 0.0;
  120. X        while (chn) {
  121. X            if (i==chn->used) {
  122. X                chn = chn->next;
  123. X                i = 0;
  124. X                continue;
  125. X            }
  126. X            if (chn->dval[i] != VERYLARGE) {
  127. X                all += chn->dval[i];
  128. X                if (!HL_me && radrad) {
  129. X                    vprev += chn->dval[i];
  130. X                    if (f->makeHL == HL_MIN && chn->dval[i] == f->d_min ||
  131. X                        f->makeHL == HL_MAX && chn->dval[i] == f->d_max ||
  132. X                        f->makeHL == j ||
  133. X                        f->makeHL == HL_NON && 
  134. X                                            (data_head.makeHL == HL_MIN && chn->dval[i] == data_head.d_min ||
  135. X                                             data_head.makeHL == HL_MAX && chn->dval[i] == data_head.d_max ||
  136. X                                              data_head.makeHL == j)) {
  137. X                        HL_me = chn->dval+i;
  138. X                        chnHL = chn;
  139. X                        numHL = i;
  140. X                        k = j;
  141. X                    }
  142. X                }
  143. X            }
  144. X            i++;
  145. X            j++;
  146. X        }
  147. X        if (f->points == 1) HL_me = NULL;
  148. X        
  149. X        if (HL_me) {
  150. X            radius = (int) (base_rad/(1+radrad));
  151. X        }
  152. X        else 
  153. X            radius = base_rad;
  154. X        
  155. X        if (HL_me) HLangle = *HL_me/all*Pi*2;
  156. X        
  157. X        if (!HL_me) {     
  158. X            chn = f->data;
  159. X            i   = 0;
  160. X            st_an = 0.0;
  161. X        }
  162. X        else {
  163. X            chn = chnHL;
  164. X            i   = numHL;
  165. X            if (explode == DEFAULT)
  166. X                st_an = incr*vprev/all*Pi*2 - incr*HLangle;
  167. X            else
  168. X                st_an = (int)explode*Pi/2 - incr*HLangle/2;
  169. X        }
  170. X        
  171. X        /* draw segments */
  172. X        lastang = angl = st_an;
  173. X        bound = chn->dval+i;
  174. X        j = k;
  175. X        do {
  176. X            if (chn->dval[i] != VERYLARGE) {
  177. X                if (!HL_me && ((chn->dval[i]/all) <= trash))
  178. X                    treshed += chn->dval[i];
  179. X                else {
  180. X                    lastang = angl;
  181. X                    angl += incr*chn->dval[i]/all*Pi*2;
  182. X                    (*t->move)(MCx(x,radius,Pi/2+angl),MCy(y,radius,Pi/2+angl));
  183. X                    (*t->vector)(x,y);
  184. X                    if (j!=k || !HL_me) {        /* if explode, don't label the first drawn element */
  185. X                        ax = MCx(x+t->h_char*cos(Pi/2+(angl+lastang)/2), radius, Pi/2+(angl+lastang)/2);
  186. X                        ay = MCy(y+t->v_char*sin(Pi/2+(angl+lastang)/2), radius, Pi/2+(angl+lastang)/2);
  187. X                        if (chn->vlbl && chn->vlbl[i])
  188. X                            lblpt = chn->vlbl[i];
  189. X                        else if (do_lab)
  190. X                            lblpt = make_labl((double)j+first_element);
  191. X                        else
  192. X                            lblpt = "";
  193. X                        strcpy(nlab, lblpt);
  194. X                        if (*nlab) strcat(nlab,"-");
  195. X                        strcat(nlab, "(");
  196. X                        strcat(nlab, make_labl(chn->dval[i]));
  197. X                        strcat(nlab, ")");
  198. X                        put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
  199. X                    }
  200. X                }
  201. X            }
  202. X            i++;
  203. X            j++;
  204. X            if (i==chn->used) {
  205. X                i=0;
  206. X                if (chn->next) chn=chn->next;
  207. X                else chn = f->data, j = 0;                /* wrap around */
  208. X            }
  209. X        } while (&chn->dval[i] != bound);
  210. X        
  211. X        /* it's possible, that the first/last radius has not been drawn */
  212. X        (*t->move)(x,y);
  213. X        (*t->vector)(MCx(x,radius,Pi/2+st_an),MCy(y,radius,Pi/2+st_an));
  214. X        
  215. X        if (HL_me) {
  216. X            lastang = Pi/2+st_an+incr*HLangle;
  217. X            put_arc(x,y,radius,st_an+incr*HLangle+Pi/2,incr*(Pi*2-HLangle));
  218. X            x += radrad*radius*cos(incr*HLangle/2+st_an+Pi/2);
  219. X            y += radrad*radius*sin(incr*HLangle/2+st_an+Pi/2);
  220. X            (*t->move)(MCx(x,radius,Pi/2+st_an),MCy(y,radius,Pi/2+st_an));
  221. X            (*t->vector)(x,y);
  222. X            (*t->vector)(MCx(x,radius,lastang),
  223. X                         MCy(y,radius,lastang));
  224. X            put_arc(x,y,radius,st_an+Pi/2,incr*HLangle);
  225. X            lastang = Pi/2+st_an+incr*HLangle/2;
  226. X            ax = MCx(x+t->h_char*cos(lastang), radius, lastang);
  227. X            ay = MCy(y+t->v_char*sin(lastang), radius, lastang);
  228. X            if (chn->vlbl && chn->vlbl[i])
  229. X                lblpt = chn->vlbl[i];
  230. X            else if (do_lab)
  231. X                lblpt = make_labl((double)j+first_element);
  232. X            else
  233. X                lblpt = "";
  234. X            strcpy(nlab, lblpt);
  235. X            strcat(nlab, "-(");
  236. X            strcat(nlab, make_labl(chn->dval[i]));
  237. X            strcat(nlab, ")");
  238. X            put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
  239. X        }
  240. X        else {
  241. X            put_arc(x,y,radius,0.0,Pi*2);
  242. X            if (treshed != 0) {
  243. X                lastang = (st_an+angl)/2 - Pi/2;    /* remainder's mediana - but why minus ??? */
  244. X                ax = MCx(x+t->h_char*cos(lastang), radius, lastang);
  245. X                ay = MCy(y+t->v_char*sin(lastang), radius, lastang);
  246. X                strcpy(nlab, thrname);
  247. X                strcat(nlab, "-(");
  248. X                strcat(nlab, make_labl(treshed));
  249. X                strcat(nlab, ")");
  250. X                put_txt(ax, ay, nlab, (ax==x) ? CENTRE : ((ax>x) ? LEFT : RIGHT), 0);
  251. X            }
  252. X        }
  253. X        
  254. X        f = f->dnxt;
  255. X        
  256. X    }  /* main loop */
  257. X    
  258. X    return(1);
  259. X}
  260. X
  261. Xdr_abar(xplot)
  262. XBOOLEAN xplot;
  263. X/* draw adjacent barchart within given values and viewport */
  264. X{
  265. X    double unit, what;
  266. X    double based = log_y ? log10(base) : base;
  267. X    int bw, ib, sp, of, gw, tw, i, j, k, pos, ibase;
  268. X    int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
  269. X    int dirNS = !((int)gravity&1);
  270. X    struct chunk *chn;
  271. X    double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
  272. X    double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
  273. X    double d_sp = (b_spc>1.0 ? b_spc/100.0 : b_spc);
  274. X    int incr = (b_clockwise ? 1 : -1), adit;
  275. X    struct dfile *f = &data_head;
  276. X    double minv, maxv, full;
  277. X    int linetype, cx, cy;
  278. X    int coff = 2*t->v_char/3;
  279. X    char *barlab, bet[200];
  280. X
  281. X    if (f->chunks == 1)
  282. X        xplot = FALSE;        /* sometimes important and faster */
  283. X
  284. X    minv = (data_head.d_min < based ? data_head.d_min : based);
  285. X    maxv = (data_head.d_max > based ? data_head.d_max : based);
  286. X    set_hm(minv, maxv);
  287. X    
  288. X    of = nint((xmaxp-xbase)*(1-MARGIN));
  289. X    xbase += of; xmaxp -= of;
  290. X    of = nint((ymaxp-ybase)*(1-MARGIN));
  291. X    ybase += of; ymaxp -= of;
  292. X
  293. X    /* reserve space for labels */
  294. X    i = xplot ? 2 : 3;
  295. X    switch (gravity) {
  296. X        case SOUTH: ybase += i*t->v_char, ymaxp -= t->v_char;
  297. X            break;
  298. X        case NORTH: ybase += t->v_char, ymaxp -= i*t->v_char;
  299. X            break;
  300. X        case EAST:  xbase += (howmuch+1)*t->h_char, xmaxp -= i*t->h_char;
  301. X            break;
  302. X        case WEST:  xbase += i*t->h_char, xmaxp -= (howmuch+1)*t->h_char;
  303. X            break;
  304. X    }
  305. X
  306. X    if (autoscale)
  307. X        adit = 0;
  308. X    else
  309. X        adit = do_axis(&minv,&maxv,xbase,xmaxp,ybase,ymaxp,FALSE);
  310. X    full = maxv-minv;
  311. X
  312. X    if (f->chunks == 1)
  313. X        unit = f->points + (f->points-1)*d_ib;
  314. X    else if (xplot)
  315. X        unit = f->chunks*f->points + (f->chunks-1)*f->points*d_ib + (f->points-1)*d_sp;
  316. X    else
  317. X        unit = f->points*f->chunks + (f->points-1)*f->chunks*d_ib + (f->chunks-1)*d_sp;
  318. X    if (!autoscale)
  319. X        unit += d_ib;
  320. X    
  321. X    bw = ((dirNS ? xmaxp-xbase : ymaxp-ybase)-adit)/unit;
  322. X    if ((double)bw/resolution > d_bw) {
  323. X        bw = resolution*d_bw;
  324. X        of = ((dirNS ? xmaxp-xbase : ymaxp-ybase) - adit - bw*unit)/2 + adit;
  325. X    }
  326. X    else of = adit;
  327. X    if (!bw) return(0);
  328. X
  329. X    ib = nint(bw*d_ib);
  330. X    if (f->chunks > 1) sp = nint(bw*d_sp);
  331. X    else sp = ib;
  332. X    gw = (xplot ? f->chunks : f->points)*(bw+ib)-ib;
  333. X    tw = nint(bw*unit);
  334. X    if (!autoscale)        /* make space between axis and bars */
  335. X        of += ib;
  336. X    resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
  337. X    unit = resolution/full;
  338. X
  339. X    (*t->linetype)(-1);
  340. X    switch (gravity) {
  341. X        case NORTH:
  342. X            (*t->move)(xbase,ibase=nint((maxv-based)*unit)+ybase);
  343. X            (*t->vector)(xmaxp-adit,ibase);
  344. X            break;
  345. X        case SOUTH:
  346. X            (*t->move)(xbase+adit,ibase=nint((based-minv)*unit)+ybase);
  347. X            (*t->vector)(xmaxp,ibase);
  348. X            break;
  349. X        case WEST:
  350. X            (*t->move)(ibase=nint((based-minv)*unit)+xbase,ybase);
  351. X            (*t->vector)(ibase,ymaxp-adit);
  352. X            break;
  353. X        case EAST:
  354. X            (*t->move)(ibase=nint((maxv-based)*unit)+xbase,ybase+adit);
  355. X            (*t->vector)(ibase,ymaxp);
  356. X            break;
  357. X        default: break;
  358. X    }
  359. X
  360. X    if (data_head.chunks > 1)
  361. X        init_acrs();
  362. X
  363. X    (*t->linetype)(linetype=0);
  364. X    for (k=0, f=f->dnxt; f; f=f->dnxt, k++) {
  365. X        j = i = 0;
  366. X        chn = f->data;
  367. X        
  368. X        if (b_clockwise) pos = of + k*(xplot ? bw+ib : gw+sp);
  369. X        else pos = of + tw - k*(xplot ? bw+ib : gw+sp) - bw; 
  370. X
  371. X        if (xplot)
  372. X            (*t->linetype)(k);
  373. X        else                     /* print plot name */
  374. X            switch (gravity) {
  375. X                case SOUTH: put_lab(xbase+pos+gw/2, ybase-5*(int)t->v_char/2, f->fname, 0, gw);
  376. X                    break;
  377. X                case NORTH: put_lab(xmaxp-pos-gw/2, ymaxp+5*(int)t->v_char/2, f->fname, 0, gw);
  378. X                    break;
  379. X                case WEST:  put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-gw/2, f->fname, 1, gw);
  380. X                    break;
  381. X                case EAST:  put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+gw/2, f->fname, 1, gw);
  382. X                    break;
  383. X            }
  384. X            
  385. X        while (chn) {
  386. X            if (i==chn->used) {
  387. X                i = 0;
  388. X                chn = chn->next;
  389. X                continue;
  390. X            }
  391. X            if ((what = chn->dval[i]) != VERYLARGE) {
  392. X                if (f->makeHL == HL_MIN && what == f->d_min ||
  393. X                    f->makeHL == HL_MAX && what == f->d_max ||
  394. X                    f->makeHL == j ||
  395. X                    data_head.makeHL == HL_MIN && what == data_head.d_min ||
  396. X                    data_head.makeHL == HL_MAX && what == data_head.d_max ||
  397. X                    data_head.makeHL == j)
  398. X                    (*t->linetype)(linetype=-1);
  399. X                if (!xplot)
  400. X                    if (chn->vlbl && chn->vlbl[i])
  401. X                        barlab = chn->vlbl[i];
  402. X                    else if (data_head.labels && f->labels)
  403. X                        strcpy(barlab=bet, make_labl((double)j+first_element));
  404. X                    else
  405. X                        barlab = NULL;
  406. X                else
  407. X                    barlab = NULL;
  408. X                switch (gravity) {
  409. X                    case SOUTH: put_bar(xbase+pos,ibase, bw,cy=nint((what-based)*unit),0);
  410. X                        put_lab(xbase+pos+bw/2, ibase+(cy>0?cy:0)+coff, make_labl(what), 0, bw);
  411. X                        put_lab(xbase+pos+bw/2, ybase-3*(int)t->v_char/2, barlab, 0, bw);
  412. X                        break;
  413. X                    case NORTH: put_bar(xmaxp-pos,ibase,-bw,cy=nint((based-what)*unit),0);
  414. X                        put_lab(xmaxp-pos-bw/2, ibase+(cy<0?cy:0)-coff, make_labl(what), 0, bw);
  415. X                        put_lab(xmaxp-pos-bw/2, ymaxp+3*(int)t->v_char/2, barlab, 0, bw);
  416. X                        break;
  417. X                    case WEST:  put_bar(ibase,ymaxp-pos-bw,cx=nint((what-based)*unit), bw,1);
  418. X                        put_txt(ibase+(cx>0?cx:0)+(int)t->h_char, ymaxp-pos-bw/2, make_labl(what), LEFT, 0);
  419. X                        put_lab(xbase-3*(int)t->h_char/2, ymaxp-pos-bw/2, barlab, 1, bw);
  420. X                        break;
  421. X                    case EAST:  put_bar(ibase,ybase+pos+bw,cx=nint((based-what)*unit),-bw,1);
  422. X                        put_txt(ibase+(cx<0?cx:0)-(int)t->h_char, ybase+pos+bw/2, make_labl(what), RIGHT, 0);
  423. X                        put_lab(xmaxp+3*(int)t->h_char/2, ybase+pos+bw/2, barlab, 1, bw);
  424. X                        break;
  425. X                }
  426. X                if (linetype != 0) (*t->linetype)(linetype=0);
  427. X            }
  428. X            if (!k && xplot) {    /* make labels */
  429. X                if (!(barlab = comm_lget()) && data_head.labels)
  430. X                    barlab = make_labl((double)j+first_element);
  431. X                switch (gravity) {
  432. X                    case SOUTH: put_lab(xbase+pos+gw/2, ybase-5*(int)t->v_char/2, barlab, 0, gw);
  433. X                        break;
  434. X                    case NORTH: put_lab(xmaxp-pos-gw/2, ymaxp+5*(int)t->v_char/2, barlab, 0, gw);
  435. X                        break;
  436. X                    case WEST:  put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-gw/2, barlab, 1, gw);
  437. X                        break;
  438. X                    case EAST:  put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+gw/2, barlab, 1, gw);
  439. X                        break;
  440. X                }
  441. X            }
  442. X                
  443. X            i++;
  444. X            j++;
  445. X            pos += incr*(xplot ? gw+sp : bw+ib);
  446. X        }
  447. X    }
  448. X
  449. X    return(1);
  450. X}
  451. X
  452. Xdr_lbar(xplot)
  453. XBOOLEAN xplot;
  454. X/* draw layered barchart within given values and viewport */
  455. X{
  456. X    double unit, dummy;
  457. X    vreal what;
  458. X    double based = log_y ? log10(base) : base;
  459. X    int bw, ib, of, i, j, k, pos, ibase, step, st_of, lbas, levels;
  460. X    int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
  461. X    int dirNS = !((int)gravity&1);
  462. X    struct chunk *chn;
  463. X    double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
  464. X    double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
  465. X    int incr = (b_clockwise ? 1 : -1);
  466. X    int grunt = ((gravity == NORTH || gravity == EAST) ? 1 : -1);
  467. X    struct dfile *f = &data_head;
  468. X    double minv, maxv, full;
  469. X    int LT, go_on;
  470. X    char *common_label;
  471. X
  472. X    if (f->chunks == 1)
  473. X        return(dr_abar(xplot));
  474. X    
  475. X    of = nint((xmaxp-xbase)*(1-MARGIN));
  476. X    xbase += of; xmaxp -= of;
  477. X    of = nint((ymaxp-ybase)*(1-MARGIN));
  478. X    ybase += of; ymaxp -= of;
  479. X
  480. X    /* reserve space for labels */
  481. X    switch (gravity) {
  482. X        case SOUTH: ybase += 3*t->v_char/2;
  483. X            break;
  484. X        case NORTH: ymaxp -= 3*t->v_char/2;
  485. X            break;
  486. X        case EAST:  xmaxp -= 3*t->h_char/2;
  487. X            break;
  488. X        case WEST:  xbase += 3*t->h_char/2;
  489. X            break;
  490. X    }    
  491. X
  492. X    if (xplot)
  493. X        unit = f->chunks + (f->chunks-1)*d_ib;
  494. X    else
  495. X        unit = f->points + (f->points-1)*d_ib;
  496. X    if (!autoscale)
  497. X        unit += d_ib;
  498. X
  499. X    bw = (dirNS ? xmaxp-xbase : ymaxp-ybase)/unit/2;
  500. X    if ((double)bw/resolution > d_bw) {
  501. X        bw = resolution*d_bw;
  502. X        of = 3*(dirNS ? xmaxp-xbase : ymaxp-ybase)/4 - bw*unit/2;
  503. X    }
  504. X    else of = (dirNS ? xmaxp-xbase : ymaxp-ybase)/2;
  505. X    if (!bw) return(0);
  506. X
  507. X    ib = nint(bw*d_ib);
  508. X    if (!autoscale)
  509. X        of += ib;
  510. X    resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
  511. X    step = resolution/(xplot ? f->points : f->chunks);
  512. X    st_of = nint(2*(1-MARGIN)*step);
  513. X    resolution = nint(step*(4*MARGIN-3));    /* resolution in pixels per one layer */
  514. X    if (resolution < 2) return(0);    
  515. X
  516. X    /* initialize xptrs */
  517. X    init_acrs();
  518. X
  519. X    levels = xplot ? data_head.points : data_head.chunks;
  520. X    lbas = grunt==1 ? (levels-1)*step : 0;
  521. X    for (f=data_head.dnxt, k=0, lbas+=st_of; k<levels; k++, lbas-=grunt*step) {
  522. X
  523. X        if (!xplot) {
  524. X            minv = f->d_min;
  525. X            maxv = f->d_max;
  526. X            go_on = TRUE;
  527. X        }
  528. X        else
  529. X            go_on = find_ran(&minv,&maxv,&dummy,&common_label);
  530. X        
  531. X        if (!xplot)
  532. X            common_label = f->fname;
  533. X        else if (common_label)
  534. X            ;
  535. X        else if (data_head.labels)
  536. X            common_label = make_labl((double)(k+first_element));
  537. X        else
  538. X            common_label = NULL;
  539. X
  540. X        (*t->linetype)(-2);
  541. X        switch (gravity) {
  542. X            case SOUTH:
  543. X                (*t->move)(xbase,j=ybase+k*step);
  544. X                (*t->vector)(xmaxp,j);
  545. X                put_txt(xbase, j+(int)t->v_char, common_label, LEFT, 0);
  546. X                break;
  547. X            case NORTH:
  548. X                (*t->move)(xbase,j=ymaxp-k*step);
  549. X                (*t->vector)(xmaxp,j);
  550. X                put_txt(xmaxp, j-(int)t->v_char, common_label, RIGHT, 0);
  551. X                break;
  552. X            case WEST:
  553. X                (*t->move)(j=xbase+k*step,ybase);
  554. X                (*t->vector)(j,ymaxp);
  555. X                put_txt(j+(int)t->v_char, ymaxp, common_label, RIGHT, 1);
  556. X                break;
  557. X            case EAST:
  558. X                (*t->move)(j=xmaxp-k*step,ybase);
  559. X                (*t->vector)(j,ymaxp);
  560. X                put_txt(j-(int)t->v_char, ybase, common_label, LEFT, 1);
  561. X                break;
  562. X        }
  563. X
  564. X        if (!go_on) continue;
  565. X        
  566. X        if (based<minv) minv=based;
  567. X        if (based>maxv) maxv=based;
  568. X        set_hm(minv, maxv);
  569. X        if (!autoscale) switch (gravity) {
  570. X            case SOUTH:
  571. X                (void) do_axis(&minv,&maxv,(xmaxp+xbase)/2,xmaxp,lbas+ybase,lbas+ybase+resolution,TRUE);
  572. X                break;
  573. X            case NORTH:
  574. X                (void) do_axis(&minv,&maxv,xbase,(xmaxp+xbase)/2,lbas+ybase,lbas+ybase+resolution,TRUE);
  575. X                break;
  576. X            case WEST:
  577. X                (void) do_axis(&minv,&maxv,lbas+xbase,lbas+xbase+resolution,ybase,(ymaxp+ybase)/2,TRUE);
  578. X                break;
  579. X            case EAST:
  580. X                (void) do_axis(&minv,&maxv,lbas+xbase,lbas+xbase+resolution,(ymaxp+ybase)/2,ymaxp,TRUE);
  581. X        }
  582. X        full = maxv-minv;
  583. X        unit = resolution/full;
  584. X        (*t->linetype)(-1);
  585. X        switch (gravity) {
  586. X            case SOUTH:
  587. X                (*t->move)((xmaxp+xbase)/2,ibase=nint((based-minv)*unit)+lbas+ybase);
  588. X                (*t->vector)(xmaxp,ibase);
  589. X                break;
  590. X            case NORTH:
  591. X                (*t->move)((xmaxp+xbase)/2,ibase=nint((maxv-based)*unit)+ybase+lbas);
  592. X                (*t->vector)(xbase,ibase);
  593. X                break;
  594. X            case WEST:
  595. X                (*t->move)(ibase=nint((based-minv)*unit)+lbas+xbase,(ymaxp+ybase)/2);
  596. X                (*t->vector)(ibase,ybase);
  597. X                break;
  598. X            case EAST:
  599. X                (*t->move)(ibase=nint((maxv-based)*unit)+xbase+lbas,(ymaxp+ybase)/2);
  600. X                (*t->vector)(ibase,ymaxp);
  601. X                break;
  602. X        }
  603. X
  604. X        if (b_clockwise) pos = of;
  605. X        else pos = of + ((xplot ? data_head.chunks : data_head.points)-1)*(bw+ib);
  606. X
  607. X        /* put bottom-row labels (there is no better time to do that ... unfortunately */
  608. X        if (!k) {
  609. X            if (xplot)
  610. X                f = data_head.dnxt;
  611. X            for (i=0; i<(xplot ? data_head.chunks : data_head.points); i++, pos+=incr*(bw+ib)) {
  612. X                if (xplot) {
  613. X                    common_label = f->fname;
  614. X                    f = f->dnxt;
  615. X                }
  616. X                else if (!(common_label = comm_lget()) && data_head.labels)
  617. X                    common_label = make_labl((double)i+first_element);
  618. X                switch (gravity) {
  619. X                    case SOUTH: put_lab(xbase+pos+bw/2, ybase-(int)t->v_char, common_label, 0, bw);
  620. X                        break;
  621. X                    case NORTH: put_lab(xmaxp-pos-bw/2, ymaxp+(int)t->v_char, common_label, 0, bw);
  622. X                        break;
  623. X                    case WEST:  put_lab(xbase-(int)t->h_char, ymaxp-pos-bw/2, common_label, 1, bw);
  624. X                        break;
  625. X                    case EAST:  put_lab(xmaxp+(int)t->h_char, ybase+pos+bw/2, common_label, 1, bw);
  626. X                        break;
  627. X                }
  628. X            }
  629. X            if (b_clockwise) pos = of;
  630. X            else pos = of + ((xplot ? data_head.chunks : data_head.points)-1)*(bw+ib);
  631. X        }
  632. X
  633. X        if (xplot) 
  634. X            for (j=0, f=data_head.dnxt; f; j++, f=f->dnxt, pos+=incr*(bw+ib)) {
  635. X                if (across[j].chnp && (what=across[j].chnp->dval[across[j].vindex]) != VERYLARGE) {
  636. X                    if (f->makeHL == HL_MIN && what == f->d_min ||
  637. X                        f->makeHL == HL_MAX && what == f->d_max ||
  638. X                        f->makeHL == k ||
  639. X                        data_head.makeHL == HL_MIN && what == data_head.d_min ||
  640. X                        data_head.makeHL == HL_MAX && what == data_head.d_max ||
  641. X                        data_head.makeHL == k)
  642. X                        (*t->linetype)(-1);
  643. X                    else
  644. X                        (*t->linetype)(j);
  645. X                    switch (gravity) {
  646. X                        case SOUTH: put_bar(xbase+pos,ibase, bw,nint((what-based)*unit),0);
  647. X                            break;
  648. X                        case NORTH: put_bar(xmaxp-pos,ibase,-bw,nint((based-what)*unit),0);
  649. X                            break;
  650. X                        case WEST:  put_bar(ibase,ymaxp-pos-bw,nint((what-based)*unit), bw,1);
  651. X                            break;
  652. X                        case EAST:  put_bar(ibase,ybase+pos+bw,nint((based-what)*unit),-bw,1);
  653. X                            break;
  654. X                    }
  655. X                }
  656. X                if (++across[j].vindex == across[j].chnp->used) {
  657. X                    across[j].vindex = 0;
  658. X                    across[j].chnp = across[j].chnp->next;
  659. X                }
  660. X            }
  661. X        else {
  662. X            (*t->linetype)(LT=0);
  663. X            for (chn=f->data, i=0, j=0; chn; ) {
  664. X                if (i==chn->used) {
  665. X                    i = 0;
  666. X                    chn = chn->next;
  667. X                    continue;
  668. X                }
  669. X                if ((what=chn->dval[i]) != VERYLARGE) {
  670. X                    if (f->makeHL == HL_MIN && what == f->d_min ||
  671. X                        f->makeHL == HL_MAX && what == f->d_max ||
  672. X                        f->makeHL == j ||
  673. X                        data_head.makeHL == HL_MIN && what == data_head.d_min ||
  674. X                        data_head.makeHL == HL_MAX && what == data_head.d_max ||
  675. X                        data_head.makeHL == j)
  676. X                        (*t->linetype)(LT=-1);
  677. X                    switch (gravity) {
  678. X                        case SOUTH: put_bar(xbase+pos,ibase, bw,nint((what-based)*unit),0);
  679. X                            break;
  680. X                        case NORTH: put_bar(xmaxp-pos,ibase,-bw,nint((based-what)*unit),0);
  681. X                            break;
  682. X                        case WEST:  put_bar(ibase,ymaxp-pos-bw,nint((what-based)*unit), bw,1);
  683. X                            break;
  684. X                        case EAST:  put_bar(ibase,ybase+pos+bw,nint((based-what)*unit),-bw,1);
  685. X                            break;
  686. X                    }
  687. X                    if (LT != 0) (*t->linetype)(LT=0);
  688. X                }
  689. X                i++;
  690. X                j++;
  691. X                pos += incr*(bw+ib);
  692. X            }
  693. X            f = f->dnxt;
  694. X        }                           
  695. X    }
  696. X
  697. X    return(1);
  698. X}
  699. X
  700. Xdr_sbar(xplot)
  701. XBOOLEAN xplot;
  702. X{
  703. X    double unit;
  704. X    vreal what;
  705. X    double based = log_y ? log10(base) : base;
  706. X    int bw, ib, of, i, j, k, pos, ibase;
  707. X    int resolution = ((int)gravity&1 ? t->ymax-2 : t->xmax-2);
  708. X    int dirNS = !((int)gravity&1);
  709. X    struct chunk *chn;
  710. X    double d_bw = (b_wid>1.0 ? b_wid/100.0 : b_wid);
  711. X    double d_ib = (b_int>1.0 ? b_int/100.0 : b_int);
  712. X    int incr = (b_clockwise ? 1 : -1), adit;
  713. X    struct dfile *f = &data_head;
  714. X    double minv=VERYLARGE, maxv=-VERYLARGE, full;
  715. X    int *bumper, LT;
  716. X    char labs[200];
  717. X
  718. X    if (xplot && f->chunks == 1) 
  719. X        return(dr_abar(xplot));
  720. X
  721. X    init_acrs();
  722. X    
  723. X    if (xplot) 
  724. X        for (j=0; j<data_head.points; j++) {
  725. X            double a1=based, a2=based;
  726. X            for (i=0; i<data_head.chunks; i++) {
  727. X                if (!across[i].chnp) continue;
  728. X                if ((what=across[i].chnp->dval[across[i].vindex]) != VERYLARGE) {
  729. X                    if (what<based) a1-=fabs(what);
  730. X                    if (what>based) a2+=fabs(what);
  731. X                }
  732. X                if (++across[i].vindex == across[i].chnp->used) {
  733. X                    across[i].vindex = 0;
  734. X                    across[i].chnp = across[i].chnp->next;
  735. X                }
  736. X            }
  737. X            if (a1<minv) minv=a1;
  738. X            if (a2>maxv) maxv=a2;
  739. X        }
  740. X    else
  741. X        for (f=data_head.dnxt; f; f=f->dnxt) {
  742. X            double a1=based, a2=based;
  743. X            chn=f->data, i=0;
  744. X            while (chn) {
  745. X                if (i==chn->used) {
  746. X                    chn=chn->next;
  747. X                    i=0;
  748. X                    continue;
  749. X                }
  750. X                else if (chn->dval[i] != VERYLARGE)
  751. X                    if (chn->dval[i]<based) a1-=fabs(chn->dval[i]);
  752. X                    else if (chn->dval[i]>based) a2+=fabs(chn->dval[i]);
  753. X                i++;
  754. X            }
  755. X            if (a1<minv) minv=a1;
  756. X            if (a2>maxv) maxv=a2;
  757. X        }
  758. X
  759. X    if (minv>based) minv=based;
  760. X    if (maxv<based) maxv=based;
  761. X    set_hm(minv, maxv);
  762. X
  763. X    of = nint((xmaxp-xbase)*(1-MARGIN));
  764. X    xbase += of; xmaxp -= of;
  765. X    of = nint((ymaxp-ybase)*(1-MARGIN));
  766. X    ybase += of; ymaxp -= of;
  767. X
  768. X    /* reserve space for labels */
  769. X    i = 2;
  770. X    switch (gravity) {
  771. X        case SOUTH: ybase += i*t->v_char, ymaxp -= t->v_char;
  772. X            break;
  773. X        case NORTH: ybase += t->v_char, ymaxp -= i*t->v_char;
  774. X            break;
  775. X        case EAST:  xbase += (howmuch+1)*t->h_char, xmaxp -= i*t->h_char;
  776. X            break;
  777. X        case WEST:  xbase += i*t->h_char, xmaxp -= (howmuch+1)*t->h_char;
  778. X            break;
  779. X    }
  780. X
  781. X    if (autoscale)
  782. X        adit = 0;
  783. X    else
  784. X        adit = do_axis(&minv,&maxv,xbase,xmaxp,ybase,ymaxp,FALSE);
  785. X    full = maxv-minv;
  786. X
  787. X    if (xplot)
  788. X        unit = data_head.points + (data_head.points-1)*d_ib;
  789. X    else
  790. X        unit = data_head.chunks + (data_head.chunks-1)*d_ib;
  791. X    if (!autoscale)
  792. X        unit += d_ib;
  793. X    
  794. X    bw = ((dirNS ? xmaxp-xbase : ymaxp-ybase)-adit)/unit;
  795. X    if ((double)bw/resolution > d_bw) {
  796. X        bw = resolution*d_bw;
  797. X        of = ((dirNS ? xmaxp-xbase : ymaxp-ybase) - adit - bw*unit)/2 + adit;
  798. X    }
  799. X    else of = adit;
  800. X    if (!bw) return(0);
  801. X    ib = nint(bw*d_ib);
  802. X    if (!autoscale)        /* make space between axis and bar */
  803. X        of += ib;
  804. X
  805. X    resolution = dirNS ? ymaxp-ybase : xmaxp-xbase;
  806. X    unit = resolution/full;
  807. X
  808. X    (*t->linetype)(-1);
  809. X    switch (gravity) {
  810. X        case NORTH:
  811. X            (*t->move)(xbase,ibase=nint((maxv-based)*unit)+ybase);
  812. X            (*t->vector)(xmaxp-adit,ibase);
  813. X            break;
  814. X        case SOUTH:
  815. X            (*t->move)(xbase+adit,ibase=nint((based-minv)*unit)+ybase);
  816. X            (*t->vector)(xmaxp,ibase);
  817. X            break;
  818. X        case WEST:
  819. X            (*t->move)(ibase=nint((based-minv)*unit)+xbase,ybase);
  820. X            (*t->vector)(ibase,ymaxp-adit);
  821. X            break;
  822. X        case EAST:
  823. X            (*t->move)(ibase=nint((maxv-based)*unit)+xbase,ybase+adit);
  824. X            (*t->vector)(ibase,ymaxp);
  825. X            break;
  826. X    }
  827. X
  828. X    if (xplot)
  829. X        for (f=data_head.dnxt, i=0; f; i++, f=f->dnxt) {
  830. X            across[i].chnp = f->data;
  831. X            across[i].vindex = 0;
  832. X        }
  833. X
  834. X    (*t->linetype)(LT=0);
  835. X    if (b_clockwise) pos = of;
  836. X    else pos = of + ((xplot ? data_head.points : data_head.chunks)-1)*(bw+ib);
  837. X    for (j=0, f=data_head.dnxt; j<(xplot?data_head.points:data_head.chunks); pos+=incr*(bw+ib), j++) {
  838. X        int above=ibase, below=ibase, aux, labfound = 1;
  839. X        BOOLEAN sense = TRUE;
  840. X        char *common_label = NULL, *chaux;
  841. X        double bsum1 = -VERYLARGE, bsum2 = -VERYLARGE;
  842. X        i = k = 0;
  843. X        if (!xplot) chn=f->data;
  844. X        else f=data_head.dnxt, k=j;
  845. X        do {
  846. X            if (xplot) {
  847. X                if (!across[i].chnp) what = VERYLARGE;
  848. X                else {
  849. X                    what = across[i].chnp->dval[across[i].vindex];
  850. X                    if (labfound && across[i].chnp->vlbl && (chaux = across[i].chnp->vlbl[across[i].vindex]))
  851. X                        if (!common_label)    /* first found */
  852. X                            common_label = chaux;
  853. X                        else
  854. X                            labfound = !strcmp(common_label,chaux);
  855. X                    if (++across[i].vindex == across[i].chnp->used) {
  856. X                        across[i].vindex = 0;
  857. X                        across[i].chnp = across[i].chnp->next;
  858. X                    }
  859. X                }
  860. X                if (++i == data_head.chunks) sense=FALSE;
  861. X            }
  862. X            else {
  863. X                if (i==chn->used) {
  864. X                    i=0;
  865. X                    sense = (chn=chn->next) != NULL;
  866. X                    continue;
  867. X                }
  868. X                what = chn->dval[i++];
  869. X            }
  870. X            if (what != VERYLARGE && what != based) {
  871. X                if (f->makeHL == HL_MIN && what == f->d_min ||
  872. X                    f->makeHL == HL_MAX && what == f->d_max ||
  873. X                    f->makeHL == k ||
  874. X                    data_head.makeHL == HL_MIN && what == data_head.d_min ||
  875. X                    data_head.makeHL == HL_MAX && what == data_head.d_max ||
  876. X                    data_head.makeHL == k)
  877. X                    (*t->linetype)(LT=-1);
  878. X                else if (xplot) (*t->linetype)(j);
  879. X                if (what>based) bumper = &above, aux=1;
  880. X                else bumper = &below, aux=-1;
  881. X                if (what >= base) {
  882. X                    what = fabs(what);
  883. X                    if (bsum1 == -VERYLARGE)
  884. X                        bsum1 = what;
  885. X                    else
  886. X                        bsum1 += what;
  887. X                }
  888. X                else  {
  889. X                    what = fabs(what);
  890. X                    if (bsum2 == -VERYLARGE)
  891. X                        bsum2 = what;
  892. X                    else
  893. X                        bsum2 += what;
  894. X                }
  895. X                switch (gravity) {
  896. X                    case SOUTH: put_bar(xbase+pos,*bumper, bw,aux*=nint(what*unit),0);
  897. X                        break;
  898. X                    case NORTH: put_bar(xmaxp-pos,*bumper,-bw,aux*=-nint(what*unit),0);
  899. X                        break;
  900. X                    case WEST:  put_bar(*bumper,ymaxp-pos-bw,aux*=nint(what*unit), bw,1);
  901. X                        break;
  902. X                    case EAST:  put_bar(*bumper,ybase+pos+bw,aux*=-nint(what*unit),-bw,1);
  903. X                        break;
  904. X                }
  905. X                *bumper += aux;
  906. X                if (LT != 0) (*t->linetype)(LT=0);
  907. X            }
  908. X            if (xplot) f=f->dnxt;
  909. X            else k++;
  910. X        } while (sense);
  911. X
  912. X        labs[0] = '\0';
  913. X        if (bsum1 != -VERYLARGE) 
  914. X            strcpy(labs, make_labl(bsum1));
  915. X        if (bsum2 != -VERYLARGE) {
  916. X            if (*labs)
  917. X                strcat(labs, "/");
  918. X            strcat(labs, make_labl(bsum2));
  919. X        }
  920. X        if (!xplot)
  921. X            common_label = f->fname;
  922. X        else if (!common_label && data_head.labels)        /* no label found, create one */
  923. X            common_label = make_labl((double)j+first_element);
  924. X        else if (!labfound)                                /* different labels */
  925. X            common_label = NULL;
  926. X        /* else coomon_label is the common label */
  927. X        
  928. X        switch (gravity) {
  929. X            case SOUTH: put_lab(xbase+pos+bw/2, above+2*(int)t->v_char/3, labs, 0, bw);
  930. X                put_lab(xbase+pos+bw/2, ybase-5*(int)t->v_char/2, common_label, 0, bw);
  931. X                break;
  932. X            case NORTH:    put_lab(xmaxp-pos-bw/2, above-2*(int)t->v_char/3, labs, 0, bw);
  933. X                put_lab(xmaxp-pos-bw/2, ymaxp+5*(int)t->v_char/2, common_label, 0, bw);
  934. X                break;
  935. X            case WEST:    put_txt(above+(int)t->h_char, ymaxp-pos-bw/2, labs, LEFT, 0); 
  936. X                put_lab(xbase-5*(int)t->h_char/2, ymaxp-pos-bw/2, common_label, 1, bw);
  937. X                break;
  938. X            case EAST:  put_txt(above-(int)t->h_char, ybase+pos+bw/2, labs, RIGHT, 0); 
  939. X                put_lab(xmaxp+5*(int)t->h_char/2, ybase+pos+bw/2, common_label, 1, bw);
  940. X                break;
  941. X            }
  942. X        if (!xplot)
  943. X            f = f->dnxt;
  944. X    }
  945. X
  946. X    return(1);
  947. X}
  948. X
  949. SHAR_EOF
  950. $TOUCH -am 0604152590 fstyles.i &&
  951. chmod 0666 fstyles.i ||
  952. echo "restore of fstyles.i failed"
  953. set `wc -c fstyles.i`;Wc_c=$1
  954. if test "$Wc_c" != "27072"; then
  955.     echo original size 27072, current size $Wc_c
  956. fi
  957. # ============= futil.c ==============
  958. echo "x - extracting futil.c (Text)"
  959. sed 's/^X//' << 'SHAR_EOF' > futil.c &&
  960. X/* Fchart - futil.c */
  961. X/*
  962. X * Gnuplot code
  963. X * Copyright (C) 1986, 1987, 1990   Thomas Williams, Colin Kelley
  964. X *
  965. X * Permission to use, copy, and distribute this software and its
  966. X * documentation for any purpose with or without fee is hereby granted,
  967. X * provided that the above copyright notice appear in all copies and
  968. X * that both that copyright notice and this permission notice appear
  969. X * in supporting documentation.
  970. X *
  971. X * Permission to modify the software is granted, but not the right to
  972. X * distribute the modified code.  Modifications are to be distributed
  973. X * as patches to released version.
  974. X *
  975. X * This software  is provided "as is" without express or implied warranty.
  976. X *
  977. X *
  978. X * AUTHORS
  979. X *
  980. X *   Original Software:
  981. X *     Thomas Williams,  Colin Kelley.
  982. X *
  983. X *   Gnuplot 2.0 additions:
  984. X *       Russell Lang, Dave Kotz, John Campbell.
  985. X *
  986. X *   Fchart changes and additions:
  987. X *       Piotr Filip Sawicki
  988. X *
  989. X * send your comments or suggestions to fs@uwasa.fi
  990. X *
  991. X */
  992. X#include <ctype.h>
  993. X#include <setjmp.h>
  994. X#include <stdio.h>
  995. X#include <errno.h>
  996. X#include "plot.h"
  997. X#include "fchart.h"
  998. X
  999. Xextern BOOLEAN screen_ok;
  1000. X    /* TRUE if command just typed; becomes FALSE whenever we
  1001. X        send some other output to screen.  If FALSE, the command line
  1002. X        will be echoed to the screen before the ^ error message. */
  1003. X
  1004. X#ifndef vms
  1005. X#ifndef __ZTC__
  1006. Xextern int errno, sys_nerr;
  1007. Xextern char *sys_errlist[];
  1008. X#endif
  1009. X#endif /* vms */
  1010. X
  1011. Xextern char input_line[];
  1012. Xextern struct lexical_unit token[];
  1013. Xextern jmp_buf env;    /* from plot.c */
  1014. X
  1015. X
  1016. X/*
  1017. X * equals() compares string value of token number t_num with str[], and
  1018. X *   returns TRUE if they are identical.
  1019. X */
  1020. Xequals(t_num, str)
  1021. Xint t_num;
  1022. Xchar *str;
  1023. X{
  1024. Xregister int i;
  1025. X
  1026. X    if (!token[t_num].is_token)
  1027. X        return(FALSE);                /* must be a value--can't be equal */
  1028. X    for (i = 0; i < token[t_num].length; i++) {
  1029. X        if (input_line[token[t_num].start_index+i] != str[i])
  1030. X            return(FALSE);
  1031. X        }
  1032. X    /* now return TRUE if at end of str[], FALSE if not */
  1033. X    return(str[i] == '\0');
  1034. X}
  1035. X
  1036. X
  1037. X
  1038. X/*
  1039. X * almost_equals() compares string value of token number t_num with str[], and
  1040. X *   returns TRUE if they are identical up to the first $ in str[].
  1041. X */
  1042. Xalmost_equals(t_num, str)
  1043. Xint t_num;
  1044. Xchar *str;
  1045. X{
  1046. Xregister int i;
  1047. Xregister int after = 0;
  1048. Xregister start = token[t_num].start_index;
  1049. Xregister length = token[t_num].length;
  1050. X
  1051. X    if (!token[t_num].is_token)
  1052. X        return(FALSE);                /* must be a value--can't be equal */
  1053. X    for (i = 0; i < length + after; i++) {
  1054. X        if (str[i] != input_line[start + i]) {
  1055. X            if (str[i] != '$')
  1056. X                return(FALSE);
  1057. X            else {
  1058. X                after = 1;
  1059. X                start--;    /* back up token ptr */
  1060. X                }
  1061. X            }
  1062. X        }
  1063. X
  1064. X    /* i now beyond end of token string */
  1065. X
  1066. X    return(after || str[i] == '$' || str[i] == '\0');
  1067. X}
  1068. X
  1069. X
  1070. X
  1071. Xisstring(t_num)
  1072. Xint t_num;
  1073. X{
  1074. X    
  1075. X    return(token[t_num].is_token &&
  1076. X           (input_line[token[t_num].start_index] == '\'' ||
  1077. X           input_line[token[t_num].start_index] == '\"'));
  1078. X}
  1079. X
  1080. X
  1081. Xisnumber(t_num)
  1082. Xint t_num;
  1083. X{
  1084. X    return(!token[t_num].is_token);
  1085. X}
  1086. X
  1087. X
  1088. X/* never used -- why ? 
  1089. Xisletter(t_num)
  1090. Xint t_num;
  1091. X{
  1092. X    return(token[t_num].is_token &&
  1093. X            (isalpha(input_line[token[t_num].start_index])));
  1094. X}
  1095. X    */
  1096. X
  1097. X
  1098. X/*
  1099. X * copy_str() copies the string in token number t_num into str, appending
  1100. X *   a null.  No more than MAX_ID_LEN chars are copied.
  1101. X *
  1102. Xcopy_str(str, t_num)
  1103. Xchar str[];
  1104. Xint t_num;
  1105. X{
  1106. Xregister int i = 0;
  1107. Xregister int start = token[t_num].start_index;
  1108. Xregister int count;
  1109. X
  1110. X    if ((count = token[t_num].length) > MAX_ID_LEN)
  1111. X        count = MAX_ID_LEN;
  1112. X    do {
  1113. X        str[i++] = input_line[start++];
  1114. X        } while (i != count);
  1115. X    str[i] = '\0';
  1116. X}
  1117. X *
  1118. X */
  1119. X
  1120. X/*
  1121. X * quote_str() does the same thing as copy_str, except it ignores the
  1122. X *   quotes at both ends.  This seems redundant, but is done for
  1123. X *   efficency.
  1124. X */
  1125. Xquote_str(str, t_num)
  1126. Xchar str[];
  1127. Xint t_num;
  1128. X{
  1129. Xregister int i = 0;
  1130. Xregister int start = token[t_num].start_index + 1;
  1131. Xregister int count;
  1132. X
  1133. X    if ((count = token[t_num].length - 2) > MAX_LINE_LEN)
  1134. X        count = MAX_LINE_LEN;
  1135. X    if (count>0) do {
  1136. X        str[i++] = input_line[start++];
  1137. X        } while (i != count);
  1138. X    str[i] = '\0';
  1139. X}
  1140. X
  1141. X
  1142. X/*
  1143. X *    capture() copies into str[] the part of input_line[] which lies between
  1144. X *    the begining of token[start] and end of token[end].
  1145. X */
  1146. Xcapture(str,start,end)
  1147. Xchar str[];
  1148. Xint start,end;
  1149. X{
  1150. Xregister int i,e;
  1151. X
  1152. X    e = token[end].start_index + token[end].length;
  1153. X    for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  1154. X        *str++ = input_line[i];
  1155. X    *str = '\0';
  1156. X}
  1157. X
  1158. X
  1159. X/*
  1160. X *    m_capture() is similar to capture(), but it mallocs storage for the
  1161. X *  string.
  1162. X */
  1163. Xm_capture(str,start,end)
  1164. Xchar **str;
  1165. Xint start,end;
  1166. X{
  1167. X    register int i,e;
  1168. X    register char *s;
  1169. X
  1170. X    if (*str)        /* previous pointer to malloc'd memory there */
  1171. X        free(*str);
  1172. X    e = token[end].start_index + token[end].length;
  1173. X    *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  1174. X    s = *str;
  1175. X    for (i = token[start].start_index; i < e && input_line[i] != '\0'; i++)
  1176. X        *s++ = input_line[i];
  1177. X    *s = '\0';
  1178. X}
  1179. X
  1180. X/*
  1181. X *    m_quote_capture() is similar to m_capture(), but it removes
  1182. X *    quotes from either end if the string.
  1183. X */
  1184. Xm_quote_capture(str,start,end)
  1185. Xchar **str;
  1186. Xint start,end;
  1187. X{
  1188. X    register int i,e;
  1189. X    register char *s;
  1190. X
  1191. X    if (*str)        /* previous pointer to malloc'd memory there */
  1192. X        free(*str);
  1193. X    e = token[end].start_index + token[end].length-1;
  1194. X    *str = alloc((unsigned int)(e - token[start].start_index + 1), "string");
  1195. X    s = *str;
  1196. X    for (i = token[start].start_index + 1; i < e && input_line[i] != '\0'; i++)
  1197. X        *s++ = input_line[i];
  1198. X    *s = '\0';
  1199. X}
  1200. X
  1201. X/* returns pointer to value of token - no checking. Bogus. Outcomented
  1202. Xconvert(val_ptr, t_num)
  1203. Xstruct value *val_ptr;
  1204. Xint t_num;
  1205. X{
  1206. X    *val_ptr = token[t_num].l_val;
  1207. X}
  1208. X    */
  1209. X
  1210. X
  1211. X/* not used 
  1212. Xdisp_value(fp,val)
  1213. XFILE *fp;
  1214. Xstruct value *val;
  1215. X{
  1216. X        switch(val->type) {
  1217. X            case INT:
  1218. X                fprintf(fp,"%d",val->v.int_val);
  1219. X                break;
  1220. X            case CMPLX:
  1221. X                if (val->v.cmplx_val.imag != 0.0 )
  1222. X                    fprintf(fp,"{%g, %g}",
  1223. X                        val->v.cmplx_val.real,val->v.cmplx_val.imag);
  1224. X                else
  1225. X                    fprintf(fp,"%g", val->v.cmplx_val.real);
  1226. X                break;
  1227. X            default:
  1228. X                int_error("unknown type in disp_value()",NO_CARET);
  1229. X        }
  1230. X}
  1231. X    */
  1232. X
  1233. Xdouble
  1234. Xreal(tok)        /* returns the real part of val */
  1235. Xint tok;
  1236. X{
  1237. X    struct value *val = &token[tok].l_val;
  1238. X    if (!isnumber(tok))
  1239. X        int_error("number expected",tok);
  1240. X    switch(val->type) {
  1241. X        case INT:
  1242. X            return((double) val->v.int_val);
  1243. X            break;
  1244. X        case CMPLX:
  1245. X            return(val->v.cmplx_val.real);
  1246. X    }
  1247. X    int_error("unknown type in real()",NO_CARET);
  1248. X    /* NOTREACHED */
  1249. X}
  1250. X
  1251. X/*
  1252. Xstruct value *
  1253. Xcomplex(a,realpart,imagpart)
  1254. Xstruct value *a;
  1255. Xdouble realpart, imagpart;
  1256. X{
  1257. X    a->type = CMPLX;
  1258. X    a->v.cmplx_val.real = realpart;
  1259. X    a->v.cmplx_val.imag = imagpart;
  1260. X    return(a);
  1261. X}
  1262. X
  1263. X
  1264. Xstruct value *
  1265. Xinteger(a,i)
  1266. Xstruct value *a;
  1267. Xint i;
  1268. X{
  1269. X    a->type = INT;
  1270. X    a->v.int_val = i;
  1271. X    return(a);
  1272. X}
  1273. X*/
  1274. X
  1275. X
  1276. Xos_error(str,t_num)
  1277. Xchar str[];
  1278. Xint t_num;
  1279. X{
  1280. X#ifdef vms
  1281. Xstatic status[2] = {1, 0};        /* 1 is count of error msgs */
  1282. X#endif
  1283. X
  1284. Xregister int i;
  1285. X
  1286. X    /* reprint line if screen has been written to */
  1287. X
  1288. X    if (t_num != NO_CARET) {        /* put caret under error */
  1289. X        if (!screen_ok)
  1290. X            fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  1291. X
  1292. X        for (i = 0; i < sizeof(PROMPT) - 1; i++)
  1293. X            (void) putc(' ',stderr);
  1294. X        for (i = 0; i < token[t_num].start_index; i++) {
  1295. X            (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  1296. X            }
  1297. X        (void) putc('^',stderr);
  1298. X        (void) putc('\n',stderr);
  1299. X    }
  1300. X
  1301. X    for (i = 0; i < sizeof(PROMPT) - 1; i++)
  1302. X        (void) putc(' ',stderr);
  1303. X    fprintf(stderr,"%s\n",str);
  1304. X
  1305. X    for (i = 0; i < sizeof(PROMPT) - 1; i++)
  1306. X        (void) putc(' ',stderr);
  1307. X#ifdef vms
  1308. X    status[1] = vaxc$errno;
  1309. X    sys$putmsg(status);
  1310. X    (void) putc('\n',stderr);
  1311. X#else
  1312. X#ifdef __ZTC__
  1313. X    fprintf(stderr,"error number %d\n\n",errno);
  1314. X#else
  1315. X    if (errno >= sys_nerr)
  1316. X        fprintf(stderr, "unknown errno %d\n\n", errno);
  1317. X    else
  1318. X        fprintf(stderr,"(%s)\n\n",sys_errlist[errno]);
  1319. X#endif
  1320. X#endif
  1321. X
  1322. X    longjmp(env, TRUE);    /* bail out to command line */
  1323. X}
  1324. X
  1325. X
  1326. Xint_error(str,t_num)
  1327. Xchar str[];
  1328. Xint t_num;
  1329. X{
  1330. Xregister int i;
  1331. X
  1332. X    /* reprint line if screen has been written to */
  1333. X
  1334. X    if (t_num != NO_CARET) {        /* put caret under error */
  1335. X        if (!screen_ok)
  1336. X            fprintf(stderr,"\n%s%s\n", PROMPT, input_line);
  1337. X
  1338. X        for (i = 0; i < sizeof(PROMPT) - 1; i++)
  1339. X            (void) putc(' ',stderr);
  1340. X        for (i = 0; i < token[t_num].start_index; i++) {
  1341. X            (void) putc((input_line[i] == '\t') ? '\t' : ' ',stderr);
  1342. X            }
  1343. X        (void) putc('^',stderr);
  1344. X        (void) putc('\n',stderr);
  1345. X    }
  1346. X
  1347. X    for (i = 0; i < sizeof(PROMPT) - 1; i++)
  1348. X        (void) putc(' ',stderr);
  1349. X    fprintf(stderr,"%s\n\n",str);
  1350. X
  1351. X    longjmp(env, TRUE);    /* bail out to command line */
  1352. X}
  1353. X
  1354. X
  1355. Xcheck_ranges(v,f)  /* check if two ranges are not overlapping */
  1356. Xstruct pair *v, *f;
  1357. X{
  1358. X    if (v->from == -1 && (!f || f->from == -1)) return(TRUE);  /* both undefined */
  1359. X    if (v->from != -1 && v->upto != -1 &&
  1360. X        v->from > v->upto) return(FALSE);  /* v range is empty */
  1361. X    if (!f) return(TRUE);  /* only v given, and it's OK */
  1362. X    if (f->from != -1 && f->upto != -1 &&
  1363. X        f->from > f->upto) return(FALSE);  /* f range is empty */
  1364. X    if (v->from == -1 || f->from == -1) return(TRUE);  /* only one defined, and it is OK */
  1365. X    /* further checking is so boring ... */
  1366. X    if (v->from < f->from) {  /* v (probably) to the left of f */
  1367. X        if (v->upto == -1 || v->upto >= f->from) return(FALSE);  /* overl. */
  1368. X    }
  1369. X    else if (v->from > f->from) {
  1370. X        if (f->upto == -1 || f->upto >= v->from) return(FALSE);
  1371. X    }
  1372. X    else return(FALSE);  /* both start in the same place */
  1373. X    return(TRUE);  /* otherwise OK */
  1374. X}
  1375. X
  1376. X            
  1377. X/* Lower-case the given string (DFK) */
  1378. X/* Done in place. */
  1379. Xvoid lower_case(s)
  1380. Xchar *s;
  1381. X{
  1382. X    register char *p = s;
  1383. X    
  1384. X    while (*p != '\0') {
  1385. X        if (isupper(*p))
  1386. X            *p = tolower(*p);
  1387. X        p++;
  1388. X    }
  1389. X}
  1390. X
  1391. X/* Squash spaces in the given string (DFK) */
  1392. X/* That is, reduce all multiple white-space chars to single spaces */
  1393. X/* Done in place. */
  1394. Xvoid squash_spaces(s)
  1395. Xchar *s;
  1396. X{
  1397. X    register char *r = s;     /* reading point */
  1398. X    register char *w = s;     /* writing point */
  1399. X    BOOLEAN space = FALSE;        /* TRUE if we've already copied a space */
  1400. X    
  1401. X    for (w = r = s; *r != '\0'; r++) {
  1402. X        if (isspace(*r)) {
  1403. X            /* white space; only copy if we haven't just copied a space */
  1404. X            if (!space) {
  1405. X                space = TRUE;
  1406. X                *w++ = ' ';
  1407. X            }               /* else ignore multiple spaces */
  1408. X        } else {
  1409. X            /* non-space character; copy it and clear flag */
  1410. X            *w++ = *r;
  1411. X            space = FALSE;
  1412. X        }
  1413. X    }
  1414. X    *w = '\0';                /* null terminate string */
  1415. X}
  1416. SHAR_EOF
  1417. $TOUCH -am 0604152590 futil.c &&
  1418. chmod 0666 futil.c ||
  1419. echo "restore of futil.c failed"
  1420. set `wc -c futil.c`;Wc_c=$1
  1421. if test "$Wc_c" != "10184"; then
  1422.     echo original size 10184, current size $Wc_c
  1423. fi
  1424. # ============= fversion.c ==============
  1425. echo "x - extracting fversion.c (Text)"
  1426. sed 's/^X//' << 'SHAR_EOF' > fversion.c &&
  1427. X/* Fchart - fversion.c */
  1428. X/*
  1429. X *  Modified version of 1.1.0 gnuplot by Thomas Williams and Colin Kelley.
  1430. X *  "You may use this code as you wish if credit is given and this message
  1431. X *  is retained."
  1432. X *
  1433. X *  Our "use" of this code has been to add a terminal driver (att 3b1),
  1434. X *  improve the IBM-PC drivers using TURBO-C routines, throw in a
  1435. X *  different help system (the one we got didn't seem to work) and add
  1436. X *  the commands SET POLAR, SET OFFSETS, and PAUSE.
  1437. X *
  1438. X *  Files that were changed from the original 1.1.0 version:
  1439. X *  command.c, graphics.c, misc.c, plot.c, term.c and version.c.
  1440. X *
  1441. X *  The annoying problem with unixplot files not being redirected by
  1442. X *  the set output command was fixed and an ``init()'' routine was
  1443. X *  added to term.c to allow an implementation to detect the terminal
  1444. X *  type.  (Currently only used by TURBO-C and VMS.)  The file term.c
  1445. X *  was further changed by breaking it into a number of .TRM files
  1446. X *  (Makefile was changed accordingly).
  1447. X *
  1448. X *  A bug in do_plot() was fixed as well as a VMS bug that caused
  1449. X *  SET OUTPUT to fail.  A final departure from the original 1.1.0
  1450. X *  version was the addition of Jyrki Yli-Nokari's HP laser jet
  1451. X *  drivers to term.c.
  1452. X *
  1453. X *  John Campbell  CAMPBELL@NAUVAX.bitnet (3b1, polar, offsets, pause)
  1454. X *  Bill Wilson    WILSON@NAUVAX.bitnet   (TURBO-C IBM-PC drivers)
  1455. X *  Steve Wampler  ...!arizona!naucse!sbw (help system acquisition)
  1456. X *
  1457. X *
  1458. X *  Fchart code by Piotr Filip Sawicki 1990
  1459. X *
  1460. X *  Main changes to Gnuplot:
  1461. X *  changed misc.c, util.c, command.c, plot.c, version.c
  1462. X *  removed eval.c, internal.c, parse.c, setshow.c, standard.c graphics.c
  1463. X *  untouched scanner.c, term.c, *.trm, help.[ch], doc utility
  1464. X *  added fgraf.c fstyles.i fonts.c flblarr.c
  1465. X *
  1466. X */
  1467. Xchar version[] = "1.0 (2D only)";
  1468. Xchar date[] = "May 1990";
  1469. Xchar bug_email[] = "fs@uwasa.fi";
  1470. Xint  patchlevel = 0;
  1471. SHAR_EOF
  1472. $TOUCH -am 0604152590 fversion.c &&
  1473. chmod 0666 fversion.c ||
  1474. echo "restore of fversion.c failed"
  1475. set `wc -c fversion.c`;Wc_c=$1
  1476. if test "$Wc_c" != "1852"; then
  1477.     echo original size 1852, current size $Wc_c
  1478. fi
  1479. # ============= titlepage.ms ==============
  1480. echo "x - extracting titlepage.ms (Text)"
  1481. sed 's/^X//' << 'SHAR_EOF' > titlepage.ms &&
  1482. X.nr HM 3.2i
  1483. X.TL
  1484. XFCHART
  1485. X.br
  1486. XAn Interactive Chart Program
  1487. X.sp
  1488. X.AU
  1489. XPiotr Filip Sawicki
  1490. X.br
  1491. XIIUW, Warsaw
  1492. X.AI
  1493. Xfs@uwasa.fi
  1494. X\*(DY
  1495. X.br
  1496. X
  1497. X
  1498. X
  1499. X
  1500. X
  1501. X
  1502. X
  1503. X
  1504. X
  1505. X
  1506. X
  1507. X
  1508. X
  1509. X
  1510. X
  1511. X
  1512. X
  1513. X
  1514. X
  1515. X
  1516. X
  1517. XThis manual is for FCHART version 1.0.
  1518. X.AB no
  1519. X.AE
  1520. X.LP
  1521. X.nr HM 1.2i
  1522. SHAR_EOF
  1523. $TOUCH -am 0604152590 titlepage.ms &&
  1524. chmod 0666 titlepage.ms ||
  1525. echo "restore of titlepage.ms failed"
  1526. set `wc -c titlepage.ms`;Wc_c=$1
  1527. if test "$Wc_c" != "214"; then
  1528.     echo original size 214, current size $Wc_c
  1529. fi
  1530. # ============= titlepage.tex ==============
  1531. echo "x - extracting titlepage.tex (Text)"
  1532. sed 's/^X//' << 'SHAR_EOF' > titlepage.tex &&
  1533. X\documentstyle{article}
  1534. X\setlength{\textwidth}{6.25in}
  1535. X\setlength{\oddsidemargin}{0.5cm}
  1536. X\setlength{\topmargin}{-0.5in}
  1537. X\setlength{\textheight}{9in}
  1538. X\setlength{\parskip}{1ex}
  1539. X\setlength{\parindent}{0pt}
  1540. X\begin{document}
  1541. X
  1542. X\pagestyle{empty}
  1543. X   \rule{0in}{3in}
  1544. X   \begin{center}
  1545. X   {\huge\bf FCHART}\\
  1546. X   \vspace{3ex}
  1547. X   {\Large An Interactive Chart Program}\\
  1548. X   \vspace{2ex}
  1549. X   \large
  1550. X   Piotr Filip Sawicki \\
  1551. X   IIUW, Warsaw \\
  1552. X   \vspace{2ex}
  1553. X   \verb+fs@uwasa.fi+
  1554. X
  1555. X   \vfill
  1556. X   {\small This manual is for Fchart version 1.0.}
  1557. X
  1558. X   \end{center}
  1559. X\newpage
  1560. X
  1561. X\tableofcontents
  1562. X\newpage
  1563. X
  1564. X\setcounter{page}{1}
  1565. X\pagestyle{myheadings}
  1566. X\markboth{FCHART 1.0}{FCHART 1.0}
  1567. X
  1568. SHAR_EOF
  1569. $TOUCH -am 0604152590 titlepage.tex &&
  1570. chmod 0666 titlepage.tex ||
  1571. echo "restore of titlepage.tex failed"
  1572. set `wc -c titlepage.tex`;Wc_c=$1
  1573. if test "$Wc_c" != "662"; then
  1574.     echo original size 662, current size $Wc_c
  1575. fi
  1576. exit 0
  1577.  
  1578.  
  1579.  
  1580.