home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 1 / 1411 < prev    next >
Encoding:
Internet Message Format  |  1990-12-28  |  42.5 KB

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