home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume24 / gnuplot3 / part02 < prev    next >
Text File  |  1991-10-26  |  49KB  |  1,955 lines

  1. Newsgroups: comp.sources.misc
  2. From: gershon%gr@cs.utah.edu (Elber Gershon)
  3. Subject:  v24i024:  gnuplot3 - interactive function plotting utility, Part02/26
  4. Message-ID: <1991Oct26.222043.6126@sparky.imd.sterling.com>
  5. X-Md4-Signature: 8c80eabd38766e4977b7667f9127fd45
  6. Date: Sat, 26 Oct 1991 22:20:43 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: gershon%gr@cs.utah.edu (Elber Gershon)
  10. Posting-number: Volume 24, Issue 24
  11. Archive-name: gnuplot3/part02
  12. Environment: UNIX, MS-DOS, VMS
  13. Supersedes: gnuplot2: Volume 11, Issue 65-79
  14.  
  15. #!/bin/sh
  16. # this is Part.02 (part 2 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file gnuplot/setshow.c continued
  19. #
  20. if test ! -r _shar_seq_.tmp; then
  21.     echo 'Please unpack part 1 first!'
  22.     exit 1
  23. fi
  24. (read Scheck
  25.  if test "$Scheck" != 2; then
  26.     echo Please unpack part "$Scheck" next!
  27.     exit 1
  28.  else
  29.     exit 0
  30.  fi
  31. ) < _shar_seq_.tmp || exit 1
  32. if test ! -f _shar_wnt_.tmp; then
  33.     echo 'x - still skipping gnuplot/setshow.c'
  34. else
  35. echo 'x - continuing file gnuplot/setshow.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/setshow.c' &&
  37. X           prev_arrow = this_arrow, this_arrow = this_arrow->next) {
  38. X          if (this_arrow->tag == tag) {
  39. X             delete_arrow(prev_arrow,this_arrow);
  40. X             return;        /* exit, our job is done */
  41. X          }
  42. X       }
  43. X       int_error("arrow not found", c_token);
  44. X    }
  45. }
  46. X
  47. /* assign a new arrow tag */
  48. /* arrows are kept sorted by tag number, so this is easy */
  49. static int                /* the lowest unassigned tag number */
  50. assign_arrow_tag()
  51. {
  52. X    struct arrow_def *this_arrow;
  53. X    int last = 0;            /* previous tag value */
  54. X
  55. X    for (this_arrow = first_arrow; this_arrow != NULL;
  56. X        this_arrow = this_arrow->next)
  57. X     if (this_arrow->tag == last+1)
  58. X       last++;
  59. X     else
  60. X       break;
  61. X
  62. X    return (last+1);
  63. }
  64. X
  65. /* delete arrow from linked list started by first_arrow.
  66. X * called with pointers to the previous arrow (prev) and the 
  67. X * arrow to delete (this).
  68. X * If there is no previous arrow (the arrow to delete is
  69. X * first_arrow) then call with prev = NULL.
  70. X */
  71. static void
  72. delete_arrow(prev,this)
  73. X    struct arrow_def *prev, *this;
  74. {
  75. X    if (this!=NULL)    {        /* there really is something to delete */
  76. X       if (prev!=NULL)        /* there is a previous arrow */
  77. X        prev->next = this->next; 
  78. X       else                /* this = first_arrow so change first_arrow */
  79. X        first_arrow = this->next;
  80. X       free((char *)this);
  81. X    }
  82. }
  83. X
  84. X
  85. enum PLOT_STYLE            /* not static; used by command.c */
  86. get_style()
  87. {
  88. register enum PLOT_STYLE ps;
  89. X
  90. X    c_token++;
  91. X    if (almost_equals(c_token,"l$ines"))
  92. X        ps = LINES;
  93. X    else if (almost_equals(c_token,"i$mpulses"))
  94. X        ps = IMPULSES;
  95. X    else if (almost_equals(c_token,"p$oints"))
  96. X        ps = POINTS;
  97. X    else if (almost_equals(c_token,"linesp$oints"))
  98. X        ps = LINESPOINTS;
  99. X    else if (almost_equals(c_token,"d$ots"))
  100. X        ps = DOTS;
  101. X    else if (almost_equals(c_token,"e$rrorbars"))
  102. X        ps = ERRORBARS;
  103. X    else
  104. X        int_error("expecting 'lines', 'points', 'linespoints', 'dots', 'impulses', or 'errorbars'",c_token);
  105. X    c_token++;
  106. X    return(ps);
  107. }
  108. X
  109. /* For set [xy]tics... command*/
  110. static void
  111. load_tics(tdef)
  112. X    struct ticdef *tdef;    /* change this ticdef */
  113. {
  114. X    if (equals(c_token,"(")) { /* set : TIC_USER */
  115. X       c_token++;
  116. X       load_tic_user(tdef);
  117. X    } else {                /* series : TIC_SERIES */
  118. X       load_tic_series(tdef);
  119. X    }
  120. }
  121. X
  122. /* load TIC_USER definition */
  123. /* (tic[,tic]...)
  124. X * where tic is ["string"] value
  125. X * Left paren is already scanned off before entry.
  126. X */
  127. static void
  128. load_tic_user(tdef)
  129. X    struct ticdef *tdef;
  130. {
  131. X    struct ticmark *list = NULL; /* start of list */
  132. X    struct ticmark *last = NULL; /* end of list */
  133. X    struct ticmark *tic = NULL; /* new ticmark */
  134. X    char temp_string[MAX_LINE_LEN];
  135. X    struct value a;
  136. X
  137. X    while (!END_OF_COMMAND) {
  138. X       /* parse a new ticmark */
  139. X       tic = (struct ticmark *)alloc(sizeof(struct ticmark), (char *)NULL);
  140. X       if (tic == (struct ticmark *)NULL) {
  141. X          free_marklist(list);
  142. X          int_error("out of memory for tic mark", c_token);
  143. X       }
  144. X
  145. X       /* has a string with it? */
  146. X       if (isstring(c_token)) {
  147. X          quote_str(temp_string,c_token);
  148. X          tic->label = alloc((unsigned int)strlen(temp_string)+1, "tic label");
  149. X          (void) strcpy(tic->label, temp_string);
  150. X          c_token++;
  151. X       } else
  152. X        tic->label = NULL;
  153. X
  154. X       /* in any case get the value */
  155. X       tic->position = real(const_express(&a));
  156. X       tic->next = NULL;
  157. X
  158. X       /* append to list */
  159. X       if (list == NULL)
  160. X        last = list = tic;    /* new list */
  161. X       else {                /* append to list */
  162. X          last->next = tic;
  163. X          last = tic;
  164. X       }
  165. X
  166. X       /* expect "," or ")" here */
  167. X       if (!END_OF_COMMAND && equals(c_token, ","))
  168. X        c_token++;        /* loop again */
  169. X       else
  170. X        break;            /* hopefully ")" */
  171. X    }
  172. X    
  173. X    if (END_OF_COMMAND || !equals(c_token, ")")) {
  174. X       free_marklist(list);
  175. X       int_error("expecting right parenthesis )", c_token);
  176. X    }
  177. X    c_token++;
  178. X    
  179. X    /* successful list */
  180. X    if (tdef->type == TIC_USER) {
  181. X       /* remove old list */
  182. X        /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  183. X       free_marklist(tdef->def.user);
  184. X       tdef->def.user = NULL;
  185. X    }
  186. X    tdef->type = TIC_USER;
  187. X    tdef->def.user = list;
  188. }
  189. X
  190. static void
  191. free_marklist(list)
  192. X    struct ticmark *list;
  193. {
  194. X    register struct ticmark *freeable;
  195. X
  196. X    while (list != NULL) {
  197. X       freeable = list;
  198. X       list = list->next;
  199. X       if (freeable->label != NULL)
  200. X        free( (char *)freeable->label );
  201. X       free( (char *)freeable );
  202. X    }
  203. }
  204. X
  205. /* load TIC_SERIES definition */
  206. /* start,incr[,end] */
  207. static void
  208. load_tic_series(tdef)
  209. X    struct ticdef *tdef;
  210. {
  211. X    double start, incr, end;
  212. X    struct value a;
  213. X    int incr_token;
  214. X
  215. X    start = real(const_express(&a));
  216. X    if (!equals(c_token, ","))
  217. X     int_error("expecting comma to separate start,incr", c_token);
  218. X    c_token++;
  219. X
  220. X    incr_token = c_token;
  221. X    incr = real(const_express(&a));
  222. X
  223. X    if (END_OF_COMMAND)
  224. X     end = VERYLARGE;
  225. X    else {
  226. X       if (!equals(c_token, ","))
  227. X        int_error("expecting comma to separate incr,end", c_token);
  228. X       c_token++;
  229. X
  230. X       end = real(const_express(&a));
  231. X    }
  232. X    if (!END_OF_COMMAND)
  233. X     int_error("tic series is defined by start,increment[,end]", 
  234. X             c_token);
  235. X    
  236. X    if (start < end && incr <= 0)
  237. X     int_error("increment must be positive", incr_token);
  238. X    if (start > end && incr >= 0)
  239. X     int_error("increment must be negative", incr_token);
  240. X    if (start > end) {
  241. X       /* put in order */
  242. X        double numtics;
  243. X        numtics = floor( (end*(1+SIGNIF) - start)/incr );
  244. X        end = start;
  245. X        start = end + numtics*incr;
  246. X        incr = -incr;
  247. /*
  248. X       double temp = start;
  249. X       start = end;
  250. X       end = temp;
  251. X       incr = -incr;
  252. X */
  253. X    }
  254. X
  255. X    if (tdef->type == TIC_USER) {
  256. X       /* remove old list */
  257. X        /* VAX Optimiser was stuffing up following line. Turn Optimiser OFF */
  258. X       free_marklist(tdef->def.user);
  259. X       tdef->def.user = NULL;
  260. X    }
  261. X    tdef->type = TIC_SERIES;
  262. X    tdef->def.series.start = start;
  263. X    tdef->def.series.incr = incr;
  264. X    tdef->def.series.end = end;
  265. }
  266. X
  267. static void
  268. load_offsets (a, b, c, d)
  269. double *a,*b, *c, *d;
  270. {
  271. struct value t;
  272. X
  273. X    *a = real (const_express(&t));  /* loff value */
  274. X    c_token++;
  275. X    if (equals(c_token,","))
  276. X        c_token++;
  277. X    if (END_OF_COMMAND) 
  278. X        return;
  279. X
  280. X    *b = real (const_express(&t));  /* roff value */
  281. X    c_token++;
  282. X    if (equals(c_token,","))
  283. X        c_token++;
  284. X    if (END_OF_COMMAND) 
  285. X        return;
  286. X
  287. X    *c = real (const_express(&t));  /* toff value */
  288. X    c_token++;
  289. X    if (equals(c_token,","))
  290. X        c_token++;
  291. X    if (END_OF_COMMAND) 
  292. X        return;
  293. X
  294. X    *d = real (const_express(&t));  /* boff value */
  295. X    c_token++;
  296. }
  297. X
  298. X
  299. BOOLEAN                    /* TRUE if a or b were changed */
  300. load_range(a,b)            /* also used by command.c */
  301. double *a,*b;
  302. {
  303. struct value t;
  304. BOOLEAN changed = FALSE;
  305. X
  306. X    if (equals(c_token,"]"))
  307. X        return(FALSE);
  308. X    if (END_OF_COMMAND) {
  309. X        int_error("starting range value or ':' or 'to' expected",c_token);
  310. X    } else if (!equals(c_token,"to") && !equals(c_token,":"))  {
  311. X        *a = real(const_express(&t));
  312. X        changed = TRUE;
  313. X    }    
  314. X    if (!equals(c_token,"to") && !equals(c_token,":"))
  315. X        int_error("':' or keyword 'to' expected",c_token);
  316. X    c_token++;
  317. X    if (!equals(c_token,"]")) {
  318. X        *b = real(const_express(&t));
  319. X        changed = TRUE;
  320. X     }
  321. X     return(changed);
  322. }
  323. X
  324. X
  325. X
  326. /******* The 'show' command *******/
  327. void
  328. show_command()
  329. {
  330. X    c_token++;
  331. X
  332. X    if (!show_one() && !show_two())
  333. X    int_error(
  334. X    "valid show options:  'action_table', 'all', 'angles', 'arrow', \n\
  335. X    'autoscale', 'border', 'clip', 'contour', 'data', 'dummy', 'format', \n\
  336. X    'function', 'grid', 'key', 'label', 'logscale', 'mapping', 'offsets', \n\
  337. X    'output', 'plot', 'parametric', 'polar', 'rrange', 'samples', \n\
  338. X    'isosamples', 'view', 'size', 'terminal', 'tics', 'ticslevel', \n\
  339. X    'time', 'title', 'trange', 'urange', 'vrange', 'variables', \n\
  340. X    'version', 'xlabel', 'xrange', 'xtics', 'xzeroaxis', 'ylabel', \n\
  341. X    'yrange', 'ytics', 'yzeroaxis', 'zlabel', 'zrange', 'ztics', 'zero', \n\
  342. X    'zeroaxis'", c_token);
  343. X    screen_ok = FALSE;
  344. X    (void) putc('\n',stderr);
  345. }
  346. X
  347. /* return TRUE if a command match, FALSE if not */
  348. static BOOLEAN
  349. show_one()
  350. {
  351. X    if (almost_equals(c_token,"ac$tion_table") ||
  352. X             equals(c_token,"at") ) {
  353. X        c_token++; 
  354. X        show_at();
  355. X        c_token++;
  356. X    }
  357. X    else if (almost_equals(c_token,"ar$row")) {
  358. X        struct value a;
  359. X        int tag = 0;
  360. X
  361. X        c_token++;
  362. X        if (!END_OF_COMMAND) {
  363. X           tag = (int)real(const_express(&a));
  364. X           if (tag <= 0)
  365. X            int_error("tag must be > zero", c_token);
  366. X        }
  367. X
  368. X        (void) putc('\n',stderr);
  369. X        show_arrow(tag);
  370. X    }
  371. X    else if (almost_equals(c_token,"au$toscale")) {
  372. X        (void) putc('\n',stderr);
  373. X        show_autoscale();
  374. X        c_token++;
  375. X    }
  376. X    else if (almost_equals(c_token,"bor$der")) {
  377. X        (void) putc('\n',stderr);
  378. X        show_border();
  379. X        c_token++;
  380. X    }
  381. X    else if (almost_equals(c_token,"c$lip")) {
  382. X        (void) putc('\n',stderr);
  383. X        show_clip();
  384. X        c_token++;
  385. X    }
  386. X    else if (almost_equals(c_token,"ma$pping")) {
  387. X        (void) putc('\n',stderr);
  388. X        show_mapping();
  389. X        c_token++;
  390. X    }
  391. X    else if (almost_equals(c_token,"co$ntour")) {
  392. X        (void) putc('\n',stderr);
  393. X        show_contour();
  394. X        c_token++;
  395. X    }
  396. X    else if (almost_equals(c_token,"d$ata")) {
  397. X        c_token++;
  398. X        if (!almost_equals(c_token,"s$tyle"))
  399. X            int_error("expecting keyword 'style'",c_token);
  400. X        (void) putc('\n',stderr);
  401. X        show_style("data",data_style);
  402. X        c_token++;
  403. X    }
  404. X    else if (almost_equals(c_token,"d$ummy")) {
  405. X          (void) fprintf(stderr,"\n\tdummy variables are \"%s\" and \"%s\"\n",
  406. X                        dummy_var[0], dummy_var[1]);
  407. X        c_token++;
  408. X    }
  409. X    else if (almost_equals(c_token,"fo$rmat")) {
  410. X        show_format();
  411. X        c_token++;
  412. X    }
  413. X    else if (almost_equals(c_token,"f$unctions")) {
  414. X        c_token++;
  415. X        if (almost_equals(c_token,"s$tyle"))  {
  416. X            (void) putc('\n',stderr);
  417. X            show_style("functions",func_style);
  418. X            c_token++;
  419. X        }
  420. X        else
  421. X            show_functions();
  422. X    }
  423. X    else if (almost_equals(c_token,"lo$gscale")) {
  424. X        (void) putc('\n',stderr);
  425. X        show_logscale();
  426. X        c_token++;
  427. X    }
  428. X    else if (almost_equals(c_token,"of$fsets")) {
  429. X        (void) putc('\n',stderr);
  430. X        show_offsets();
  431. X        c_token++;
  432. X    }
  433. X    else if (almost_equals(c_token,"o$utput")) {
  434. X        (void) putc('\n',stderr);
  435. X        show_output();
  436. X        c_token++;
  437. X    }
  438. X    else if (almost_equals(c_token,"tit$le")) {
  439. X        (void) putc('\n',stderr);
  440. X        show_title();
  441. X        c_token++;
  442. X    }
  443. X    else if (almost_equals(c_token,"xl$abel")) {
  444. X        (void) putc('\n',stderr);
  445. X        show_xlabel();
  446. X        c_token++;
  447. X    }
  448. X    else if (almost_equals(c_token,"yl$abel")) {
  449. X        (void) putc('\n',stderr);
  450. X        show_ylabel();
  451. X        c_token++;
  452. X    }
  453. X    else if (almost_equals(c_token,"zl$abel")) {
  454. X        (void) putc('\n',stderr);
  455. X        show_zlabel();
  456. X        c_token++;
  457. X    }
  458. X    else if (almost_equals(c_token,"xzero$axis")) {
  459. X        (void) putc('\n',stderr);
  460. X        show_xzeroaxis();
  461. X        c_token++;
  462. X    }
  463. X    else if (almost_equals(c_token,"yzero$axis")) {
  464. X        (void) putc('\n',stderr);
  465. X        show_yzeroaxis();
  466. X        c_token++;
  467. X    }
  468. X    else if (almost_equals(c_token,"zeroa$xis")) {
  469. X        (void) putc('\n',stderr);
  470. X        show_xzeroaxis();
  471. X        show_yzeroaxis();
  472. X        c_token++;
  473. X    }
  474. X    else if (almost_equals(c_token,"la$bel")) {
  475. X        struct value a;
  476. X        int tag = 0;
  477. X
  478. X        c_token++;
  479. X        if (!END_OF_COMMAND) {
  480. X           tag = (int)real(const_express(&a));
  481. X           if (tag <= 0)
  482. X            int_error("tag must be > zero", c_token);
  483. X        }
  484. X
  485. X        (void) putc('\n',stderr);
  486. X        show_label(tag);
  487. X    }
  488. X    else if (almost_equals(c_token,"g$rid")) {
  489. X        (void) putc('\n',stderr);
  490. X        show_grid();
  491. X        c_token++;
  492. X    }
  493. X    else if (almost_equals(c_token,"k$ey")) {
  494. X        (void) putc('\n',stderr);
  495. X        show_key();
  496. X        c_token++;
  497. X    }
  498. X    else
  499. X        return (FALSE);
  500. X    return TRUE;
  501. }
  502. X
  503. /* return TRUE if a command match, FALSE if not */
  504. static BOOLEAN
  505. show_two()
  506. {
  507. X    if (almost_equals(c_token,"p$lot")) {
  508. X        (void) putc('\n',stderr);
  509. X        show_plot();
  510. X        c_token++;
  511. X    }
  512. X    else if (almost_equals(c_token,"par$ametric")) {
  513. X        (void) putc('\n',stderr);
  514. X        show_parametric();
  515. X        c_token++;
  516. X    }
  517. X    else if (almost_equals(c_token,"pol$ar")) {
  518. X        (void) putc('\n',stderr);
  519. X        show_polar();
  520. X        c_token++;
  521. X    }
  522. X    else if (almost_equals(c_token,"an$gles")) {
  523. X        (void) putc('\n',stderr);
  524. X        show_angles();
  525. X        c_token++;
  526. X    }
  527. X    else if (almost_equals(c_token,"ti$cs")) {
  528. X        (void) putc('\n',stderr);
  529. X        show_tics(TRUE,TRUE,TRUE);
  530. X        c_token++;
  531. X    }
  532. X    else if (almost_equals(c_token,"tim$e")) {
  533. X        (void) putc('\n',stderr);
  534. X        show_time();
  535. X        c_token++;
  536. X    }
  537. X    else if (almost_equals(c_token,"su$rface")) {
  538. X        (void) putc('\n',stderr);
  539. X        show_surface();
  540. X        c_token++;
  541. X    }
  542. X    else if (almost_equals(c_token,"xti$cs")) {
  543. X        show_tics(TRUE,FALSE,FALSE);
  544. X        c_token++;
  545. X    }
  546. X    else if (almost_equals(c_token,"yti$cs")) {
  547. X        show_tics(FALSE,TRUE,FALSE);
  548. X        c_token++;
  549. X    }
  550. X    else if (almost_equals(c_token,"zti$cs")) {
  551. X        show_tics(FALSE,FALSE,TRUE);
  552. X        c_token++;
  553. X    }
  554. X    else if (almost_equals(c_token,"sa$mples")) {
  555. X        (void) putc('\n',stderr);
  556. X        show_samples();
  557. X        c_token++;
  558. X    }
  559. X    else if (almost_equals(c_token,"isosa$mples")) {
  560. X        (void) putc('\n',stderr);
  561. X        show_isosamples();
  562. X        c_token++;
  563. X    }
  564. X    else if (almost_equals(c_token,"si$ze")) {
  565. X        (void) putc('\n',stderr);
  566. X        show_size();
  567. X        c_token++;
  568. X    }
  569. X    else if (almost_equals(c_token,"t$erminal")) {
  570. X        (void) putc('\n',stderr);
  571. X        show_term();
  572. X        c_token++;
  573. X    }
  574. X    else if (almost_equals(c_token,"rr$ange")) {
  575. X        (void) putc('\n',stderr);
  576. X        show_range('r',rmin,rmax);
  577. X        c_token++;
  578. X    }
  579. X    else if (almost_equals(c_token,"tr$ange")) {
  580. X        (void) putc('\n',stderr);
  581. X        show_range('t',tmin,tmax);
  582. X        c_token++;
  583. X    }
  584. X    else if (almost_equals(c_token,"ur$ange")) {
  585. X        (void) putc('\n',stderr);
  586. X        show_range('u',umin,umax);
  587. X        c_token++;
  588. X    }
  589. X    else if (almost_equals(c_token,"vi$ew")) {
  590. X        (void) putc('\n',stderr);
  591. X        show_view();
  592. X        c_token++;
  593. X    }
  594. X    else if (almost_equals(c_token,"vr$ange")) {
  595. X        (void) putc('\n',stderr);
  596. X        show_range('v',vmin,vmax);
  597. X        c_token++;
  598. X    }
  599. X    else if (almost_equals(c_token,"v$ariables")) {
  600. X        show_variables();
  601. X        c_token++;
  602. X    }
  603. X    else if (almost_equals(c_token,"ve$rsion")) {
  604. X        show_version();
  605. X        c_token++;
  606. X    }
  607. X    else if (almost_equals(c_token,"xr$ange")) {
  608. X        (void) putc('\n',stderr);
  609. X        show_range('x',xmin,xmax);
  610. X        c_token++;
  611. X    }
  612. X    else if (almost_equals(c_token,"yr$ange")) {
  613. X        (void) putc('\n',stderr);
  614. X        show_range('y',ymin,ymax);
  615. X        c_token++;
  616. X    }
  617. X    else if (almost_equals(c_token,"zr$ange")) {
  618. X        (void) putc('\n',stderr);
  619. X        show_range('z',zmin,zmax);
  620. X        c_token++;
  621. X    }
  622. X    else if (almost_equals(c_token,"z$ero")) {
  623. X        (void) putc('\n',stderr);
  624. X        show_zero();
  625. X        c_token++;
  626. X    }
  627. X    else if (almost_equals(c_token,"a$ll")) {
  628. X        c_token++;
  629. X        show_version();
  630. X        show_autoscale();
  631. X        show_border();
  632. X        show_clip();
  633. X        show_contour();
  634. X        show_mapping();
  635. X          (void) fprintf(stderr,"\tdummy variables are \"%s\" and \"%s\"\n",
  636. X                        dummy_var[0], dummy_var[1]);
  637. X        show_format();
  638. X        show_style("data",data_style);
  639. X        show_style("functions",func_style);
  640. X        show_grid();
  641. X        show_label(0);
  642. X        show_arrow(0);
  643. X        show_key();
  644. X        show_logscale();
  645. X        show_offsets();
  646. X        show_output();
  647. X        show_parametric();
  648. X        show_polar();
  649. X        show_angles();
  650. X        show_samples();
  651. X        show_isosamples();
  652. X        show_view();
  653. X        show_surface();
  654. X        show_size();
  655. X        show_term();
  656. X        show_tics(TRUE,TRUE,TRUE);
  657. X        show_time();
  658. X        if (parametric)
  659. X            if (!is_3d_plot)
  660. X                show_range('t',tmin,tmax);
  661. X            else {
  662. X                show_range('u',umin,umax);
  663. X                show_range('v',vmin,vmax);
  664. X            }
  665. X        if (polar)
  666. X          show_range('r',rmin,rmax);
  667. X        show_range('x',xmin,xmax);
  668. X        show_range('y',ymin,ymax);
  669. X        show_range('z',zmin,zmax);
  670. X        show_title();
  671. X        show_xlabel();
  672. X        show_ylabel();
  673. X        show_zlabel();
  674. X        show_zero();
  675. X        show_plot();
  676. X        show_variables();
  677. X        show_functions();
  678. X        c_token++;
  679. X    }
  680. X    else
  681. X        return (FALSE);
  682. X    return (TRUE);
  683. }
  684. X
  685. X
  686. /*********** support functions for 'show'  **********/
  687. static void
  688. show_style(name,style)
  689. char name[];
  690. enum PLOT_STYLE style;
  691. {
  692. X    fprintf(stderr,"\t%s are plotted with ",name);
  693. X    switch (style) {
  694. X        case LINES: fprintf(stderr,"lines\n"); break;
  695. X        case POINTS: fprintf(stderr,"points\n"); break;
  696. X        case IMPULSES: fprintf(stderr,"impulses\n"); break;
  697. X        case LINESPOINTS: fprintf(stderr,"linespoints\n"); break;
  698. X        case DOTS: fprintf(stderr,"dots\n"); break;
  699. X        case ERRORBARS: fprintf(stderr,"errorbars\n"); break;
  700. X    }
  701. }
  702. X
  703. static void
  704. show_range(name,min,max)
  705. char name;
  706. double min,max;
  707. {
  708. X    fprintf(stderr,"\t%crange is [%g : %g]\n",name,min,max);
  709. }
  710. X
  711. static void
  712. show_zero()
  713. {
  714. X    fprintf(stderr,"\tzero is %g\n",zero);
  715. }
  716. X
  717. static void
  718. show_offsets()
  719. {
  720. X    fprintf(stderr,"\toffsets are %g, %g, %g, %g\n",loff,roff,toff,boff);
  721. }
  722. X
  723. static void
  724. show_border()
  725. {
  726. X    fprintf(stderr,"\tborder is %sdrawn\n", draw_border ? "" : "not ");
  727. }
  728. X
  729. static void
  730. show_output()
  731. {
  732. X    fprintf(stderr,"\toutput is sent to %s\n",outstr);
  733. }
  734. X
  735. static void
  736. show_samples()
  737. {
  738. X    fprintf(stderr,"\tsampling rate is %d\n",samples);
  739. }
  740. X
  741. static void
  742. show_isosamples()
  743. {
  744. X    fprintf(stderr,"\tiso sampling rate is %d\n",iso_samples);
  745. }
  746. X
  747. static void
  748. show_surface()
  749. {
  750. X    fprintf(stderr,"\tsurface is %sdrawn\n", draw_surface ? "" : "not ");
  751. }
  752. X
  753. static void
  754. show_view()
  755. {
  756. X    fprintf(stderr,"\tview is %g rot_x, %g rot_z, %g scale, %g scale_z\n",
  757. X        surface_rot_x, surface_rot_z, surface_scale, surface_zscale);
  758. }
  759. X
  760. static void
  761. show_size()
  762. {
  763. X    fprintf(stderr,"\tsize is scaled by %g,%g\n",xsize,ysize);
  764. }
  765. X
  766. static void
  767. show_title()
  768. {
  769. X    fprintf(stderr,"\ttitle is \"%s\", offset at %d, %d\n",
  770. X        title,title_xoffset,title_yoffset);
  771. }
  772. X
  773. static void
  774. show_xlabel()
  775. {
  776. X    fprintf(stderr,"\txlabel is \"%s\", offset at %d, %d\n",
  777. X        xlabel,xlabel_xoffset,xlabel_yoffset);
  778. }
  779. X
  780. static void
  781. show_ylabel()
  782. {
  783. X    fprintf(stderr,"\tylabel is \"%s\", offset at %d, %d\n",
  784. X        ylabel,ylabel_xoffset,ylabel_yoffset);
  785. }
  786. static void
  787. show_zlabel()
  788. {
  789. X    fprintf(stderr,"\tzlabel is \"%s\", offset at %d, %d\n",
  790. X        zlabel,zlabel_xoffset,zlabel_yoffset);
  791. }
  792. X
  793. static void
  794. show_xzeroaxis()
  795. {
  796. X    fprintf(stderr,"\txzeroaxis is %s\n",(xzeroaxis)? "ON" : "OFF");
  797. }
  798. X
  799. static void
  800. show_yzeroaxis()
  801. {
  802. X    fprintf(stderr,"\tyzeroaxis is %s\n",(yzeroaxis)? "ON" : "OFF");
  803. }
  804. X
  805. static void
  806. show_label(tag)
  807. X    int tag;                /* 0 means show all */
  808. {
  809. X    struct text_label *this_label;
  810. X    BOOLEAN showed = FALSE;
  811. X
  812. X    for (this_label = first_label; this_label != NULL;
  813. X        this_label = this_label->next) {
  814. X       if (tag == 0 || tag == this_label->tag) {
  815. X          showed = TRUE;
  816. X          fprintf(stderr,"\tlabel %d \"%s\" at %g,%g,%g ",
  817. X                this_label->tag, this_label->text, 
  818. X                this_label->x, this_label->y, this_label->z);
  819. X          switch(this_label->pos) {
  820. X             case LEFT : {
  821. X                fprintf(stderr,"left");
  822. X                break;
  823. X             }
  824. X             case CENTRE : {
  825. X                fprintf(stderr,"centre");
  826. X                break;
  827. X             }
  828. X             case RIGHT : {
  829. X                fprintf(stderr,"right");
  830. X                break;
  831. X             }
  832. X          }
  833. X          fputc('\n',stderr);
  834. X       }
  835. X    }
  836. X    if (tag > 0 && !showed)
  837. X     int_error("label not found", c_token);
  838. }
  839. X
  840. static void
  841. show_arrow(tag)
  842. X    int tag;                /* 0 means show all */
  843. {
  844. X    struct arrow_def *this_arrow;
  845. X    BOOLEAN showed = FALSE;
  846. X
  847. X    for (this_arrow = first_arrow; this_arrow != NULL;
  848. X        this_arrow = this_arrow->next) {
  849. X       if (tag == 0 || tag == this_arrow->tag) {
  850. X          showed = TRUE;
  851. X          fprintf(stderr,"\tarrow %d from %g,%g,%g to %g,%g,%g%s\n",
  852. X                this_arrow->tag, 
  853. X                this_arrow->sx, this_arrow->sy, this_arrow->sz,
  854. X                this_arrow->ex, this_arrow->ey, this_arrow->ez,
  855. X                this_arrow->head ? "" : " (nohead)");
  856. X       }
  857. X    }
  858. X    if (tag > 0 && !showed)
  859. X     int_error("arrow not found", c_token);
  860. }
  861. X
  862. static void
  863. show_grid()
  864. {
  865. X    fprintf(stderr,"\tgrid is %s\n",(grid)? "ON" : "OFF");
  866. }
  867. X
  868. static void
  869. show_key()
  870. {
  871. X    switch (key) {
  872. X        case -1 : 
  873. X            fprintf(stderr,"\tkey is ON\n");
  874. X            break;
  875. X        case 0 :
  876. X            fprintf(stderr,"\tkey is OFF\n");
  877. X            break;
  878. X        case 1 :
  879. X            fprintf(stderr,"\tkey is at %g,%g,%g\n",key_x,key_y,key_z);
  880. X            break;
  881. X    }
  882. }
  883. X
  884. static void
  885. show_parametric()
  886. {
  887. X    fprintf(stderr,"\tparametric is %s\n",(parametric)? "ON" : "OFF");
  888. }
  889. X
  890. static void
  891. show_polar()
  892. {
  893. X    fprintf(stderr,"\tpolar is %s\n",(polar)? "ON" : "OFF");
  894. }
  895. X
  896. static void
  897. show_angles()
  898. {
  899. X    fprintf(stderr,"\tAngles are in ");
  900. X    switch (angles_format) {
  901. X        case ANGLES_RADIANS:
  902. X            fprintf(stderr, "radians\n");
  903. X        break;
  904. X        case ANGLES_DEGREES:
  905. X            fprintf(stderr, "degrees\n");
  906. X        break;
  907. X    }
  908. }
  909. X
  910. X
  911. static void
  912. show_tics(showx, showy, showz)
  913. X    BOOLEAN showx, showy, showz;
  914. {
  915. X    fprintf(stderr,"\ttics are %s, ",(tic_in)? "IN" : "OUT");
  916. X    fprintf(stderr,"\tticslevel is %g\n",ticslevel);
  917. X
  918. X    if (showx)
  919. X     show_ticdef(xtics, 'x', &xticdef);
  920. X    if (showy)
  921. X     show_ticdef(ytics, 'y', &yticdef);
  922. X    if (showz)
  923. X     show_ticdef(ztics, 'z', &zticdef);
  924. X    screen_ok = FALSE;
  925. }
  926. X
  927. /* called by show_tics */
  928. static void
  929. show_ticdef(tics, axis, tdef)
  930. X    BOOLEAN tics;            /* xtics ytics or ztics */
  931. X    char axis;            /* 'x' 'y' or 'z' */
  932. X    struct ticdef *tdef;    /* xticdef yticdef or zticdef */
  933. {
  934. X    register struct ticmark *t;
  935. X
  936. X    fprintf(stderr, "\t%c-axis tic labelling is ", axis);
  937. X    if (!tics) {
  938. X       fprintf(stderr, "OFF\n");
  939. X       return;
  940. X    }
  941. X
  942. X    switch(tdef->type) {
  943. X       case TIC_COMPUTED: {
  944. X          fprintf(stderr, "computed automatically\n");
  945. X          break;
  946. X       }
  947. X       case TIC_SERIES: {
  948. X          if (tdef->def.series.end == VERYLARGE)
  949. X            fprintf(stderr, "series from %g by %g\n", 
  950. X                  tdef->def.series.start, tdef->def.series.incr);
  951. X          else
  952. X            fprintf(stderr, "series from %g by %g until %g\n", 
  953. X                  tdef->def.series.start, tdef->def.series.incr, 
  954. X                  tdef->def.series.end);
  955. X          break;
  956. X       }
  957. X       case TIC_USER: {
  958. X          fprintf(stderr, "list (");
  959. X          for (t = tdef->def.user; t != NULL; t=t->next) {
  960. X             if (t->label)
  961. X               fprintf(stderr, "\"%s\" ", t->label);
  962. X             if (t->next)
  963. X               fprintf(stderr, "%g, ", t->position);
  964. X             else
  965. X               fprintf(stderr, "%g", t->position);
  966. X          }
  967. X          fprintf(stderr, ")\n");
  968. X          break;
  969. X       }
  970. X       default: {
  971. X          int_error("unknown ticdef type in show_ticdef()", NO_CARET);
  972. X          /* NOTREACHED */
  973. X       }
  974. X    }
  975. }
  976. X
  977. static void
  978. show_time()
  979. {
  980. X    fprintf(stderr,"\ttime is %s, offset at %d, %d\n",
  981. X        (timedate)? "ON" : "OFF",
  982. X        time_xoffset,time_yoffset);
  983. }
  984. X
  985. static void
  986. show_term()
  987. {
  988. X    char *str;
  989. X
  990. X    fprintf(stderr,"\tterminal type is %s %s\n",
  991. X        term_tbl[term].name, term_options);
  992. }
  993. X
  994. static void
  995. show_plot()
  996. {
  997. X    fprintf(stderr,"\tlast plot command was: %s\n",replot_line);
  998. }
  999. X
  1000. static void
  1001. show_autoscale()
  1002. {
  1003. X    fprintf(stderr,"\tautoscaling is ");
  1004. X    if (parametric)
  1005. X        if (is_3d_plot)
  1006. X            fprintf(stderr,"\tt: %s, ",(autoscale_t)? "ON" : "OFF");
  1007. X        else
  1008. X            fprintf(stderr,"\tu: %s, v: %s, ",
  1009. X                        (autoscale_u)? "ON" : "OFF",
  1010. X                        (autoscale_v)? "ON" : "OFF");
  1011. X    else fprintf(stderr,"\t");
  1012. X
  1013. X    if (polar) fprintf(stderr,"r: %s, ",(autoscale_r)? "ON" : "OFF");
  1014. X    fprintf(stderr,"x: %s, ",(autoscale_x)? "ON" : "OFF");
  1015. X    fprintf(stderr,"y: %s, ",(autoscale_y)? "ON" : "OFF");
  1016. X    fprintf(stderr,"z: %s\n",(autoscale_z)? "ON" : "OFF");
  1017. }
  1018. X
  1019. static void
  1020. show_clip()
  1021. {
  1022. X    fprintf(stderr,"\tpoint clip is %s\n",(clip_points)? "ON" : "OFF");
  1023. X
  1024. X    if (clip_lines1)
  1025. X      fprintf(stderr,
  1026. X         "\tdrawing and clipping lines between inrange and outrange points\n");
  1027. X    else
  1028. X      fprintf(stderr,
  1029. X         "\tnot drawing lines between inrange and outrange points\n");
  1030. X
  1031. X    if (clip_lines2)
  1032. X      fprintf(stderr,
  1033. X         "\tdrawing and clipping lines between two outrange points\n");
  1034. X    else
  1035. X      fprintf(stderr,
  1036. X         "\tnot drawing lines between two outrange points\n");
  1037. }
  1038. X
  1039. static void
  1040. show_mapping()
  1041. {
  1042. X    fprintf(stderr,"\tmapping for 3-d data is ");
  1043. X
  1044. X    switch (mapping3d) {
  1045. X        case MAP3D_CARTESIAN:
  1046. X            fprintf(stderr,"cartesian\n");
  1047. X            break;
  1048. X        case MAP3D_SPHERICAL:
  1049. X            fprintf(stderr,"spherical\n");
  1050. X            break;
  1051. X        case MAP3D_CYLINDRICAL:
  1052. X            fprintf(stderr,"cylindrical\n");
  1053. X            break;
  1054. X    }
  1055. }
  1056. X
  1057. static void
  1058. show_contour()
  1059. {
  1060. X    fprintf(stderr,"\tcontour for surfaces are %s",
  1061. X        (draw_contour)? "drawn" : "not drawn\n");
  1062. X
  1063. X    if (draw_contour) {
  1064. X            fprintf(stderr, " in %d levels on ", contour_levels);
  1065. X        switch (draw_contour) {
  1066. X            case CONTOUR_BASE:
  1067. X                fprintf(stderr,"grid base\n");
  1068. X                break;
  1069. X            case CONTOUR_SRF:
  1070. X                fprintf(stderr,"surface\n");
  1071. X                break;
  1072. X            case CONTOUR_BOTH:
  1073. X                fprintf(stderr,"grid base and surface\n");
  1074. X                break;
  1075. X        }
  1076. X        switch (contour_kind) {
  1077. X            case CONTOUR_KIND_LINEAR:
  1078. X                fprintf(stderr,"\t\tas linear segments\n");
  1079. X                break;
  1080. X            case CONTOUR_KIND_CUBIC_SPL:
  1081. X                fprintf(stderr,"\t\tas cubic spline interpolation segments with %d pts\n",
  1082. X                    contour_pts);
  1083. X                break;
  1084. X            case CONTOUR_KIND_BSPLINE:
  1085. X                fprintf(stderr,"\t\tas bspline approximation segments of order %d with %d pts\n",
  1086. X                    contour_order, contour_pts);
  1087. X                break;
  1088. X        }
  1089. X    }
  1090. }
  1091. X
  1092. static void
  1093. show_format()
  1094. {
  1095. X    fprintf(stderr, "\ttic format is x-axis: \"%s\", y-axis: \"%s\", z-axis: \"%s\"\n",
  1096. X        xformat, yformat, zformat);
  1097. }
  1098. X
  1099. static void
  1100. show_logscale()
  1101. {
  1102. X    char *p;
  1103. X
  1104. X    if (log_x && log_y && log_z)
  1105. X        fprintf(stderr,"\tlogscaling all x, y and z axes\n");
  1106. X    else {
  1107. X        p = (log_x && log_y)              /* Look for pairs. */
  1108. X             ? "x and y"
  1109. X             :  (log_x && log_z)
  1110. X                     ? "x and z"
  1111. X                     :  (log_y && log_z)
  1112. X                     ? "y and z"
  1113. X                     : NULL;
  1114. X        if (p != NULL)
  1115. X            fprintf(stderr,"\tlogscaling both %s axes\n",p);
  1116. X        else {
  1117. X            if (log_x)
  1118. X                fprintf(stderr,"\tlogscaling x axis\n");
  1119. X            if (log_y)
  1120. X                fprintf(stderr,"\tlogscaling y axis\n");
  1121. X            if (log_z)
  1122. X                fprintf(stderr,"\tlogscaling z axis\n");
  1123. X            if (!(log_x || log_y || log_z))
  1124. X                fprintf(stderr,"\tno logscaling\n");
  1125. X        }
  1126. X    }
  1127. }
  1128. X
  1129. static void
  1130. show_variables()
  1131. {
  1132. register struct udvt_entry *udv = first_udv;
  1133. int len;
  1134. X
  1135. X    fprintf(stderr,"\n\tVariables:\n");
  1136. X    while (udv) {
  1137. X         len = instring(udv->udv_name, ' ');
  1138. X        fprintf(stderr,"\t%-*s ",len,udv->udv_name);
  1139. X        if (udv->udv_undef)
  1140. X            fputs("is undefined\n",stderr);
  1141. X        else {
  1142. X            fputs("= ",stderr);
  1143. X            disp_value(stderr,&(udv->udv_value));
  1144. X            (void) putc('\n',stderr);
  1145. X        }
  1146. X        udv = udv->next_udv;
  1147. X    }
  1148. }
  1149. X
  1150. void                /* used by plot.c */
  1151. show_version()
  1152. {
  1153. extern char version[];
  1154. extern char patchlevel[];
  1155. extern char date[];
  1156. extern char bug_email[];
  1157. static char *authors[] = {"Thomas Williams","Colin Kelley"}; /* primary */
  1158. int x;
  1159. long time();
  1160. X
  1161. X    x = time((long *)NULL) & 1;
  1162. X    fprintf(stderr,"\n\t%s\n\t%sversion %s\n",
  1163. X        PROGRAM, OS, version); 
  1164. X    fprintf(stderr,"\tpatchlevel %s\n",patchlevel);
  1165. X     fprintf(stderr, "\tlast modified %s\n", date);
  1166. X    fprintf(stderr,"\tCopyright (C) 1986, 1987, 1990, 1991  %s, %s\n",
  1167. X        authors[x],authors[1-x]);
  1168. X    fprintf(stderr, "\n\tSend bugs and comments to %s\n", bug_email);
  1169. }
  1170. X
  1171. X
  1172. X
  1173. X
  1174. X
  1175. X
  1176. X
  1177. X
  1178. SHAR_EOF
  1179. echo 'File gnuplot/setshow.c is complete' &&
  1180. chmod 0644 gnuplot/setshow.c ||
  1181. echo 'restore of gnuplot/setshow.c failed'
  1182. Wc_c="`wc -c < 'gnuplot/setshow.c'`"
  1183. test 63352 -eq "$Wc_c" ||
  1184.     echo 'gnuplot/setshow.c: original size 63352, current size' "$Wc_c"
  1185. rm -f _shar_wnt_.tmp
  1186. fi
  1187. # ============= gnuplot/README ==============
  1188. if test -f 'gnuplot/README' -a X"$1" != X"-c"; then
  1189.     echo 'x - skipping gnuplot/README (File already exists)'
  1190.     rm -f _shar_wnt_.tmp
  1191. else
  1192. > _shar_wnt_.tmp
  1193. echo 'x - extracting gnuplot/README (Text)'
  1194. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/README' &&
  1195. X
  1196. X                   Where to get updates to GNUPLOT
  1197. X
  1198. Congratulations on getting this version of GNUPLOT! Unfortunately, it
  1199. may not be the most recent version ("you never know where this version
  1200. has been!"). You can be sure that it IS the most recent version by
  1201. checking one of the official distribution sites, guaranteed to be kept
  1202. up to date (of course, if you got this file from one of those sites,
  1203. you don't need to check!).
  1204. X
  1205. To hear automatically about future releases (and other GNUPLOT news),
  1206. join the mailing list; see below.
  1207. X
  1208. At the time of this writing, the following are the official
  1209. distribution sites and transfer instructions. Note that
  1210. prep.ai.mit.edu is NOT an official site, and may not be up to date.
  1211. Also, comp.sources.misc is usually a month or so behind us.
  1212. X
  1213. Date: Wed Sep 18 20:45:52 EDT 1991
  1214. Version: 3.0
  1215. X
  1216. In general, GNUPLOT 3.0 is available as the file gnuplot3.0.tar.Z.
  1217. There are no patches that bring GNUPLOT 2.02 up to 3.0, so you must
  1218. obtain the whole new release. Please obtain gnuplot from the site
  1219. nearest you.
  1220. X
  1221. USENET users:
  1222. X
  1223. X    GNUPLOT 3.0 was posted to comp.sources.misc.
  1224. X
  1225. X
  1226. NORTH AMERICA:
  1227. X
  1228. X     Anonymous ftp to dartmouth.edu (129.170.16.4)
  1229. X     Fetch
  1230. X        pub/gnuplot/gnuplot3.0.tar.Z
  1231. X     in binary mode.
  1232. X
  1233. X     Users without ftp capability can obtain it through a mail ftp
  1234. X     server. Send a mail message saying 'help' to
  1235. X     BITFTP@pucc.princeton.edu for instructions. For a uuencoded
  1236. X     copy of the gnuplot sources (compressed tar file), send this
  1237. X     message to BITFTP@pucc.princeton.edu:
  1238. X         FTP DARTMOUTH.EDU UUENCODE
  1239. X         USER ANONYMOUS
  1240. X         CD pub/gnuplot
  1241. X         BINARY
  1242. X         GET gnuplot3.0.tar.Z
  1243. X         QUIT
  1244. X
  1245. X
  1246. AUSTRALIA:
  1247. X
  1248. X     Anonymous ftp to monu1.cc.monash.edu.au (130.194.1.101).
  1249. X     Fetch pub/gnuplot3.0.tar.Z in binary mode.
  1250. X
  1251. X
  1252. EUROPE:
  1253. X
  1254. X     Anonymous ftp to irisa.irisa.fr (131.254.2.3).
  1255. X     Fetch pub/gnuplot3.0.tar.Z in binary mode.
  1256. X
  1257. ----
  1258. X
  1259. X     DISCLAIMER - This product is not related in any way to
  1260. X     Pixar or any other commercial venture.
  1261. X
  1262. ----
  1263. X  CONTACTS:
  1264. X     Please send any questions or comments to
  1265. X        pixar!info-gnuplot@ucbvax.berkeley.edu.
  1266. X     To join the above mailing list (or get yourself off), mail to
  1267. X        pixar!info-gnuplot-request@ucbvax.berkeley.edu.
  1268. X     Send bug reports and problems to
  1269. X        pixar!bug-gnuplot@ucbvax.berkeley.edu.
  1270. X
  1271. X                                        -Thomas Williams-
  1272. SHAR_EOF
  1273. chmod 0644 gnuplot/README ||
  1274. echo 'restore of gnuplot/README failed'
  1275. Wc_c="`wc -c < 'gnuplot/README'`"
  1276. test 2406 -eq "$Wc_c" ||
  1277.     echo 'gnuplot/README: original size 2406, current size' "$Wc_c"
  1278. rm -f _shar_wnt_.tmp
  1279. fi
  1280. # ============= gnuplot/help.c ==============
  1281. if test -f 'gnuplot/help.c' -a X"$1" != X"-c"; then
  1282.     echo 'x - skipping gnuplot/help.c (File already exists)'
  1283.     rm -f _shar_wnt_.tmp
  1284. else
  1285. > _shar_wnt_.tmp
  1286. echo 'x - extracting gnuplot/help.c (Text)'
  1287. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/help.c' &&
  1288. /* GNUPLOT - help.c */
  1289. /*
  1290. X * Copyright (C) 1986, 1987, 1990, 1991   Thomas Williams, Colin Kelley
  1291. X *
  1292. X * Permission to use, copy, and distribute this software and its
  1293. X * documentation for any purpose with or without fee is hereby granted, 
  1294. X * provided that the above copyright notice appear in all copies and 
  1295. X * that both that copyright notice and this permission notice appear 
  1296. X * in supporting documentation.
  1297. X *
  1298. X * Permission to modify the software is granted, but not the right to
  1299. X * distribute the modified code.  Modifications are to be distributed 
  1300. X * as patches to released version.
  1301. X *  
  1302. X * This software is provided "as is" without express or implied warranty.
  1303. X * 
  1304. X *
  1305. X * AUTHORS
  1306. X * 
  1307. X *   Original Software:
  1308. X *     Thomas Williams,  Colin Kelley.
  1309. X * 
  1310. X *   Gnuplot 2.0 additions:
  1311. X *       Russell Lang, Dave Kotz, John Campbell.
  1312. X *
  1313. X *   Gnuplot 3.0 additions:
  1314. X *       Gershon Elber and many others.
  1315. X * 
  1316. X * Send your comments or suggestions to 
  1317. X *  pixar!info-gnuplot@sun.com.
  1318. X * This is a mailing list; to join it send a note to 
  1319. X *  pixar!info-gnuplot-request@sun.com.  
  1320. X * Send bug reports to
  1321. X *  pixar!bug-gnuplot@sun.com.
  1322. X */
  1323. X
  1324. #include <stdio.h>
  1325. X
  1326. extern int errno;
  1327. X
  1328. extern int strcmp();
  1329. extern int strlen();
  1330. extern char *strcpy();
  1331. extern char *strncpy();
  1332. extern char *strcat();
  1333. extern char *strncat();
  1334. extern char *getenv();
  1335. extern FILE *fopen();
  1336. extern char *malloc();
  1337. X
  1338. extern int instring();
  1339. X
  1340. #define    SAME    0    /* for strcmp() */
  1341. X
  1342. #include "help.h"    /* values passed back */
  1343. X
  1344. /* help -- help subsystem that understands defined keywords
  1345. **
  1346. ** Looks for the desired keyword in the help file at runtime, so you
  1347. ** can give extra help or supply local customizations by merely editing
  1348. ** the help file.
  1349. **
  1350. ** The original (single-file) idea and algorithm is by John D. Johnson,
  1351. ** Hewlett-Packard Company.  Thanx and a tip of the Hatlo hat!
  1352. **
  1353. ** Much extension by David Kotz for use in gnutex, and then in gnuplot.
  1354. ** Added output paging support, both unix and builtin. Rewrote completely
  1355. ** to read helpfile into memory, avoiding reread of help file. 12/89.
  1356. **
  1357. ** Modified by Russell Lang to avoid reading completely into memory
  1358. ** if MSDOS defined.  This uses much less memory.  6/91
  1359. **
  1360. ** The help file looks like this (the question marks are really in column 1):
  1361. **
  1362. **     ?topic
  1363. **     This line is printed when the user wants help on "topic".
  1364. **     ?keyword
  1365. **     ?Keyword
  1366. **     ?KEYWORD
  1367. **     These lines will be printed on the screen if the user wanted
  1368. **     help on "keyword", "Keyword", or "KEYWORD".  No casefolding is
  1369. **    done on the keywords.
  1370. **     ?subject
  1371. **     ?alias
  1372. **     This line is printed for help on "subject" and "alias".
  1373. **     ?
  1374. **    ??
  1375. **     Since there is a null keyword for this line, this section
  1376. **     is printed when the user wants general help (when a help
  1377. **     keyword isn't given).  A command summary is usually here.
  1378. **    Notice that the null keyword is equivalent to a "?" keyword
  1379. **    here, because of the '?' and '??' topic lines above.
  1380. **   If multiple keywords are given, the first is considered the 
  1381. **   'primary' keyword. This affects a listing of available topics.
  1382. **     ?last-subject
  1383. **     Note that help sections are terminated by the start of the next
  1384. **     '?' entry or by EOF.  So you can't have a leading '?' on a line
  1385. **     of any help section.  You can re-define the magic character to
  1386. **    recognize in column 1, though, if '?' is too useful.  (Try ^A.)
  1387. */
  1388. X
  1389. #define    KEYFLAG    '?'    /* leading char in help file topic lines */
  1390. X
  1391. /*
  1392. ** Calling sequence:
  1393. **    int result;        # 0 == success
  1394. **    char *keyword;        # topic to give help on
  1395. **    char *pathname;        # path of help file
  1396. **      int subtopics;        # set to TRUE if only subtopics to be listed
  1397. **                # returns TRUE if subtopics were found
  1398. **    result = help(keyword, pathname, &subtopics);
  1399. ** Sample:
  1400. **    cmd = "search\n";
  1401. **    helpfile = "/usr/local/lib/program/program.help";
  1402. **    subtopics = FALSE;
  1403. **    if (help(cmd, helpfile, &subtopics) != H_FOUND)
  1404. **        printf("Sorry, no help for %s", cmd);
  1405. **
  1406. **
  1407. ** Speed this up by replacing the stdio calls with open/close/read/write.
  1408. */
  1409. #ifdef    WDLEN
  1410. #  define    PATHSIZE    WDLEN
  1411. #else
  1412. #  define    PATHSIZE    BUFSIZ
  1413. #endif
  1414. X
  1415. typedef int boolean;
  1416. #ifndef TRUE
  1417. #define TRUE (1)
  1418. #define FALSE (0)
  1419. #endif
  1420. X
  1421. typedef struct line_s LINEBUF;
  1422. struct line_s {
  1423. X    char *line;            /* the text of this line */
  1424. X    LINEBUF *next;            /* the next line */
  1425. };
  1426. X
  1427. typedef struct linkey_s LINKEY;
  1428. struct linkey_s {
  1429. X    char *key;                /* the name of this key */
  1430. X    long pos;                /* ftell position */
  1431. X    LINEBUF *text;            /* the text for this key */
  1432. X    boolean primary;        /* TRUE -> is a primary name for a text block */
  1433. X    LINKEY *next;            /* the next key in linked list */
  1434. };
  1435. X
  1436. typedef struct key_s KEY;
  1437. struct key_s {
  1438. X    char *key;                /* the name of this key */
  1439. X    long pos;                /* ftell position */
  1440. X    LINEBUF *text;            /* the text for this key */
  1441. X    boolean primary;        /* TRUE -> is a primary name for a text block */
  1442. };
  1443. static LINKEY *keylist = NULL;    /* linked list of keys */
  1444. static KEY *keys = NULL;        /* array of keys */
  1445. static int keycount = 0;        /* number of keys */
  1446. static FILE *helpfp = NULL;
  1447. X
  1448. static int LoadHelp();
  1449. static void sortkeys();
  1450. static int keycomp();
  1451. static LINEBUF *storeline();
  1452. static LINKEY *storekey();
  1453. static KEY *FindHelp();
  1454. static boolean Ambiguous();
  1455. X
  1456. /* Help output */
  1457. static void PrintHelp();
  1458. static void ShowSubtopics();
  1459. static void StartOutput();
  1460. static void OutLine();
  1461. static void EndOutput();
  1462. static FILE *outfile;        /* for unix pager, if any */
  1463. static int pagelines;        /* count for builtin pager */
  1464. #define SCREENSIZE 24        /* lines on screen (most have at least 24) */
  1465. X
  1466. /* help:
  1467. X * print a help message 
  1468. X * also print available subtopics, if subtopics is TRUE
  1469. X */
  1470. help(keyword, path, subtopics)
  1471. X    char *keyword;        /* on this topic */
  1472. X    char *path;            /* from this file */
  1473. X    boolean *subtopics;    /* (in) - subtopics only? */
  1474. X                        /* (out) - are there subtopics? */
  1475. {
  1476. X    static char oldpath[PATHSIZE] = "";    /* previous help file */
  1477. X    int status;            /* result of LoadHelp */
  1478. X    KEY *key;            /* key that matches keyword */
  1479. X
  1480. X    /*
  1481. X    ** Load the help file if necessary (say, first time we enter this routine,
  1482. X    ** or if the help file changes from the last time we were called).
  1483. X    ** Also may occur if in-memory copy was freed.
  1484. X    ** Calling routine may access errno to determine cause of H_ERROR.
  1485. X    */
  1486. X    errno = 0;
  1487. X    if (strncmp(oldpath, path, PATHSIZE) != SAME)
  1488. X     FreeHelp();
  1489. X    if (keys == NULL) {
  1490. X       status = LoadHelp(path);
  1491. X       if (status == H_ERROR)
  1492. X        return(status);
  1493. X
  1494. X       /* save the new path in oldpath */
  1495. X       if (strlen(path) < PATHSIZE)
  1496. X        (void) strcpy(oldpath, path);
  1497. X       else {                /* not enough room in oldpath, sigh */
  1498. X          (void) strncpy(oldpath, path, PATHSIZE - 1);
  1499. X          oldpath[PATHSIZE - 1] = '\0';
  1500. X       }
  1501. X    }
  1502. X
  1503. X    /* look for the keyword in the help file */
  1504. X    key = FindHelp(keyword);
  1505. X    if (key != NULL) {
  1506. X       /* found the keyword: print help and return */
  1507. X       PrintHelp(key, subtopics);
  1508. X       status = H_FOUND;
  1509. X    } else {
  1510. X       status = H_NOTFOUND;
  1511. X    }
  1512. X
  1513. X    return(status);
  1514. }
  1515. X
  1516. /* we only read the file once, into memory
  1517. X * except for MSDOS when we don't read all the file -
  1518. X * just the keys and location of the text
  1519. X */
  1520. static int
  1521. LoadHelp(path)
  1522. X    char *path;
  1523. {
  1524. X    LINKEY *key;            /* this key */
  1525. X    long pos;                /* ftell location within help file */
  1526. X    char buf[BUFSIZ];        /* line from help file */
  1527. X    LINEBUF *head;            /* head of text list  */
  1528. X    LINEBUF *firsthead = NULL;
  1529. X    boolean primary;        /* first ? line of a set is primary */
  1530. X    boolean flag;
  1531. X
  1532. X    if ((helpfp = fopen(path, "r")) == NULL) {
  1533. X       /* can't open help file, so error exit */
  1534. X       return (H_ERROR);
  1535. X    }
  1536. X
  1537. X    /*
  1538. X    ** The help file is open.  Look in there for the keyword.
  1539. X    */
  1540. X    (void) fgets(buf, BUFSIZ - 1, helpfp);
  1541. X    while (!feof(helpfp)) {
  1542. X       /*
  1543. X        ** Make an entry for each synonym keyword
  1544. X        */
  1545. X       primary = TRUE;
  1546. X       while (buf[0] == KEYFLAG) {
  1547. X          key = storekey(buf+1);    /* store this key */
  1548. X          key->primary = primary;
  1549. X          key->text = NULL;            /* fill in with real value later */
  1550. X          key->pos = 0;                /* fill in with real value later */
  1551. X          primary = FALSE;
  1552. X          pos = ftell(helpfp);
  1553. X          if (fgets(buf, BUFSIZ - 1, helpfp) == (char *)NULL)
  1554. X            break;
  1555. X       }
  1556. X       /*
  1557. X        ** Now store the text for this entry.
  1558. X        ** buf already contains the first line of text.
  1559. X        */
  1560. #ifndef MSDOS
  1561. X       firsthead = storeline(buf);
  1562. X       head = firsthead;
  1563. #endif
  1564. X       while ( (fgets(buf, BUFSIZ - 1, helpfp) != (char *)NULL)
  1565. X        && (buf[0] != KEYFLAG) ){
  1566. #ifndef MSDOS
  1567. X          /* save text line */
  1568. X          head->next = storeline(buf);
  1569. X          head = head->next;
  1570. #endif
  1571. X       }
  1572. X       /* make each synonym key point to the same text */
  1573. X       do {
  1574. X          key->pos = pos;
  1575. X          key->text = firsthead;
  1576. X          flag = key->primary;
  1577. X          key = key->next;
  1578. X       } while ( flag!=TRUE  &&  key!=NULL );
  1579. X    }
  1580. #ifndef MSDOS
  1581. X    (void) fclose(helpfp);
  1582. #endif
  1583. X
  1584. X    /* we sort the keys so we can use binary search later */
  1585. X    sortkeys();
  1586. X    return(H_FOUND); /* ok */
  1587. }
  1588. X
  1589. /* make a new line buffer and save this string there */
  1590. static LINEBUF *
  1591. storeline(text)
  1592. X    char *text;
  1593. {
  1594. X    LINEBUF *new;
  1595. X
  1596. X    new = (LINEBUF *)malloc(sizeof(LINEBUF));
  1597. X    if (new == NULL)
  1598. X     int_error("not enough memory to store help file", -1);
  1599. X    if (text != NULL) {
  1600. X       new->line = (char *) malloc((unsigned int)(strlen(text)+1));
  1601. X       if (new->line == NULL)
  1602. X        int_error("not enough memory to store help file", -1);
  1603. X       (void) strcpy(new->line, text);
  1604. X    } else
  1605. X     new->line = NULL;
  1606. X
  1607. X    new->next = NULL;
  1608. X
  1609. X    return(new);
  1610. }
  1611. X
  1612. /* Add this keyword to the keys list, with the given text */
  1613. static LINKEY *
  1614. storekey(key)
  1615. X    char *key;
  1616. {
  1617. X    LINKEY *new;
  1618. X
  1619. X    key[strlen(key)-1] = '\0'; /* cut off \n  */
  1620. X
  1621. X    new = (LINKEY *)malloc(sizeof(LINKEY));
  1622. X    if (new == NULL)
  1623. X     int_error("not enough memory to store help file", -1);
  1624. X    new->key = (char *) malloc((unsigned int)(strlen(key)+1));
  1625. X    if (new->key == NULL)
  1626. X     int_error("not enough memory to store help file", -1);
  1627. X    (void) strcpy(new->key, key);
  1628. X
  1629. X    /* add to front of list */
  1630. X    new->next = keylist;
  1631. X    keylist = new;
  1632. X    keycount++;
  1633. X    return(new);
  1634. }
  1635. X
  1636. /* we sort the keys so we can use binary search later */
  1637. /* We have a linked list of keys and the number.
  1638. X * to sort them we need an array, so we reform them into an array,
  1639. X * and then throw away the list.
  1640. X */
  1641. static void
  1642. sortkeys()
  1643. {
  1644. X    LINKEY *p,*n;            /* pointers to linked list */
  1645. X    int i;                /* index into key array */
  1646. X    
  1647. X    /* allocate the array */
  1648. X    keys = (KEY *)malloc((unsigned int)((keycount+1) * sizeof(KEY)));
  1649. X    if (keys == NULL)
  1650. X     int_error("not enough memory to store help file", -1);
  1651. X    
  1652. X    /* copy info from list to array, freeing list */
  1653. X    for (p = keylist, i = 0; p != NULL; p = n, i++) {
  1654. X       keys[i].key = p->key;
  1655. X       keys[i].pos = p->pos;
  1656. X       keys[i].text = p->text;
  1657. X       keys[i].primary = p->primary;
  1658. X       n = p->next;
  1659. X       free( (char *)p );
  1660. X    }
  1661. X
  1662. X    /* a null entry to terminate subtopic searches */
  1663. X    keys[keycount].key = NULL;
  1664. X    keys[keycount].pos = 0;
  1665. X    keys[keycount].text = NULL;
  1666. X
  1667. X    /* sort the array */
  1668. X    /* note that it only moves objects of size (two pointers + long + int) */
  1669. X    /* it moves no strings */
  1670. X    qsort((char *)keys, keycount, sizeof(KEY), keycomp);
  1671. }
  1672. X
  1673. static int
  1674. keycomp(a, b)
  1675. X    KEY *a,*b;
  1676. {
  1677. X    return (strcmp(a->key, b->key));
  1678. }
  1679. X
  1680. /* Free the help file from memory. */
  1681. /* May be called externally if space is needed */
  1682. void
  1683. FreeHelp()
  1684. {
  1685. X    int i;                /* index into keys[] */
  1686. X    LINEBUF *t, *next;
  1687. X
  1688. X    if (keys == NULL)
  1689. X     return;
  1690. X
  1691. X    for (i = 0; i < keycount; i++) {
  1692. X       free( (char *)keys[i].key );
  1693. X       if (keys[i].primary)   /* only try to release text once! */
  1694. X       for (t = keys[i].text; t != NULL; t = next) {
  1695. X          free( (char *)t->line );
  1696. X          next = t->next;
  1697. X          free( (char *)t );
  1698. X       }
  1699. X    }
  1700. X    free( (char *)keys );
  1701. X    keys = NULL;
  1702. X    keycount = 0;
  1703. #ifdef MSDOS
  1704. X    (void) fclose(helpfp);
  1705. #endif
  1706. }
  1707. X
  1708. /* FindHelp:
  1709. X *  Find the key that matches the keyword.
  1710. X *  The keys[] array is sorted by key.
  1711. X *  We could use a binary search, but a linear search will aid our
  1712. X *  attempt to allow abbreviations. We search for the first thing that
  1713. X *  matches all the text we're given. If not an exact match, then
  1714. X *  it is an abbreviated match, and there must be no other abbreviated
  1715. X *  matches -- for if there are, the abbreviation is ambiguous. 
  1716. X *  We print the ambiguous matches in that case, and return not found.
  1717. X */
  1718. static KEY *                /* NULL if not found */
  1719. FindHelp(keyword)
  1720. X    char *keyword;            /* string we look for */
  1721. {
  1722. X    KEY *key;
  1723. X    int len = strlen(keyword);
  1724. X    int compare;
  1725. X
  1726. X    for (key = keys, compare = 1; key->key != NULL && compare > 0; key++) {
  1727. X       compare = strncmp(keyword, key->key, len);
  1728. X       if (compare == 0)    /* we have a match! */
  1729. X        if (!Ambiguous(key, len)) {
  1730. X            /* non-ambiguous abbreviation */
  1731. X            (void) strcpy(keyword, key->key); /* give back the full spelling */
  1732. X            return(key);        /* found!! */
  1733. X        }
  1734. X    }
  1735. X
  1736. X    /* not found, or ambiguous */
  1737. X    return(NULL);
  1738. }
  1739. X
  1740. /* Ambiguous:
  1741. X * Check the key for ambiguity up to the given length.
  1742. X * It is ambiguous if it is not a complete string and there are other
  1743. X * keys following it with the same leading substring.
  1744. X */
  1745. static boolean
  1746. Ambiguous(key, len)
  1747. X    KEY *key;
  1748. X    int len;
  1749. {
  1750. X    char *first;
  1751. X    char *prev;
  1752. X    boolean status = FALSE;    /* assume not ambiguous */
  1753. X    int compare;
  1754. X    int sublen;
  1755. X
  1756. X    if (key->key[len] == '\0')
  1757. X     return(FALSE);
  1758. X    
  1759. X    for (prev = first = key->key, compare = 0, key++;
  1760. X        key->key != NULL && compare == 0; key++) {
  1761. X       compare = strncmp(first, key->key, len);
  1762. X       if (compare == 0) {
  1763. X          /* So this key matches the first one, up to len.
  1764. X           * But is it different enough from the previous one
  1765. X           * to bother printing it as a separate choice?
  1766. X           */
  1767. X          sublen = instring(prev+len, ' ');
  1768. X          if (strncmp(key->key, prev, len+sublen) != 0) {
  1769. X             /* yup, this is different up to the next space */
  1770. X             if (!status) {
  1771. X                /* first one we have printed is special */
  1772. X                fprintf(stderr, 
  1773. X                       "Ambiguous request '%.*s'; possible matches:\n",
  1774. X                       len, first);
  1775. X                fprintf(stderr, "\t%s\n", prev);
  1776. X                status = TRUE;
  1777. X             }
  1778. X             fprintf(stderr, "\t%s\n", key->key);
  1779. X             prev = key->key;
  1780. X          }
  1781. X       }
  1782. X    }
  1783. X    
  1784. X    return(status);
  1785. }
  1786. X
  1787. /* PrintHelp:
  1788. X * print the text for key
  1789. X */
  1790. static void
  1791. PrintHelp(key, subtopics)
  1792. X    KEY *key;
  1793. X    boolean *subtopics;        /* (in) - subtopics only? */
  1794. X                        /* (out) - are there subtopics? */
  1795. {
  1796. X    LINEBUF *t;
  1797. #ifdef MSDOS
  1798. X    char buf[BUFSIZ];        /* line from help file */
  1799. #endif
  1800. X
  1801. X    StartOutput();
  1802. X
  1803. X    if (subtopics == NULL || !*subtopics) {
  1804. #ifdef MSDOS
  1805. X       fseek(helpfp,key->pos,0);
  1806. X       while ( (fgets(buf, BUFSIZ - 1, helpfp) != (char *)NULL)
  1807. X            && (buf[0] != KEYFLAG) ) {
  1808. X          OutLine(buf);
  1809. X       }
  1810. #else
  1811. X       for (t = key->text; t != NULL; t = t->next)
  1812. X        OutLine(t->line);        /* print text line */
  1813. #endif
  1814. X    }
  1815. X
  1816. X    ShowSubtopics(key, subtopics);
  1817. X    OutLine("\n");
  1818. X
  1819. X    EndOutput();
  1820. }
  1821. X
  1822. /* ShowSubtopics:
  1823. X *  Print a list of subtopic names
  1824. X */
  1825. #define PER_LINE 4
  1826. X
  1827. static void
  1828. ShowSubtopics(key, subtopics)
  1829. X    KEY *key;                /* the topic */
  1830. X    boolean *subtopics;        /* (out) are there any subtopics */
  1831. {
  1832. X    int subt = 0;            /* printed any subtopics yet? */
  1833. X    KEY *subkey;            /* subtopic key */
  1834. X    int len;                /* length of key name */
  1835. X    char line[BUFSIZ];        /* subtopic output line */
  1836. X    char *start;            /* position of subname in key name */
  1837. X    int sublen;            /* length of subname */
  1838. X    int pos;
  1839. X    char *prev = NULL;        /* the last thing we put on the list */
  1840. X
  1841. X    *line = '\0';
  1842. X    len = strlen(key->key);
  1843. X
  1844. X    for (subkey = key+1; subkey->key != NULL; subkey++) {
  1845. X       if (strncmp(subkey->key, key->key, len) == 0) {
  1846. X          /* find this subtopic name */
  1847. X          start = subkey->key + len;
  1848. X          if (len > 0)
  1849. X            if (*start == ' ')
  1850. X             start++;        /* skip space */
  1851. X            else
  1852. X             break;        /* not the same topic after all  */
  1853. X          else            /* here we are looking for main topics */
  1854. X            if (!subkey->primary)
  1855. X             continue;    /* not a main topic */
  1856. X          sublen = instring(start, ' ');
  1857. X          if (prev == NULL || strncmp(start, prev, sublen) != 0) {
  1858. X             if (subt == 0) {
  1859. X                subt++;
  1860. X                if (len)
  1861. X                  (void) sprintf(line, "\nSubtopics available for %s:\n", 
  1862. X                        key->key);
  1863. X                else
  1864. X                  (void) sprintf(line, "\nHelp topics available:\n");
  1865. X                OutLine(line);
  1866. X                *line = '\0';
  1867. X                pos = 0;
  1868. X             }
  1869. X             if (pos == PER_LINE) {
  1870. X                (void) strcat(line, "\n");
  1871. X                OutLine(line);
  1872. X                *line = '\0';
  1873. X                pos = 0;
  1874. X             }
  1875. X             (void) strcat(line, "\t");
  1876. X             (void) strncat(line, start, sublen);
  1877. X             pos++;
  1878. X             prev = start;
  1879. X          }
  1880. X       } else {
  1881. X          /* new topic */
  1882. X          break;
  1883. X       }
  1884. X    }
  1885. X    
  1886. X    /* put out the last line */
  1887. X    if (subt > 0 && pos > 0) {
  1888. X       (void) strcat(line, "\n");
  1889. X       OutLine(line);
  1890. X    }
  1891. X    
  1892. /*
  1893. X    if (subt == 0) {
  1894. X       OutLine("\n");
  1895. X       OutLine("No subtopics available\n");
  1896. X    }
  1897. */
  1898. X    
  1899. X    if (subtopics)
  1900. X     *subtopics = (subt != 0);
  1901. }
  1902. X
  1903. X
  1904. /* StartOutput:
  1905. X * Open a file pointer to a pipe to user's $PAGER, if there is one,
  1906. X * otherwise use our own pager.
  1907. X */
  1908. static void
  1909. StartOutput()
  1910. {
  1911. #ifdef unix
  1912. X    char *pager_name = getenv("PAGER");
  1913. X    extern FILE *popen();
  1914. X
  1915. X    if (pager_name != NULL && *pager_name != '\0')
  1916. X     if ((outfile = popen(pager_name, "w")) != (FILE *)NULL)
  1917. X       return;            /* success */
  1918. X    outfile = stderr;
  1919. X    /* fall through to built-in pager */
  1920. #endif
  1921. X
  1922. X    /* built-in pager */
  1923. X    pagelines = 0;
  1924. }
  1925. X
  1926. /* write a line of help output  */
  1927. /* line should contain only one \n, at the end */
  1928. static void
  1929. OutLine(line)
  1930. X    char *line;
  1931. {
  1932. X    int c;                /* dummy input char */
  1933. #ifdef unix
  1934. X    if (outfile != stderr) {
  1935. X       fputs(line, outfile);
  1936. X       return;
  1937. X    }
  1938. #endif
  1939. X
  1940. X    /* built-in dumb pager */
  1941. SHAR_EOF
  1942. true || echo 'restore of gnuplot/help.c failed'
  1943. fi
  1944. echo 'End of  part 2'
  1945. echo 'File gnuplot/help.c is continued in part 3'
  1946. echo 3 > _shar_seq_.tmp
  1947. exit 0
  1948.  
  1949. exit 0 # Just in case...
  1950. -- 
  1951. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1952. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1953. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1954. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1955.