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

  1. Newsgroups: comp.sources.misc
  2. From: gershon%gr@cs.utah.edu (Elber Gershon)
  3. Subject:  v24i036:  gnuplot3 - interactive function plotting utility, Part14/26
  4. Message-ID: <1991Oct28.002238.12335@sparky.imd.sterling.com>
  5. X-Md4-Signature: d825bc892c4ef1a2029f0e6ad80fb265
  6. Date: Mon, 28 Oct 1991 00:22:38 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 36
  11. Archive-name: gnuplot3/part14
  12. Environment: UNIX, MS-DOS, VMS
  13. Supersedes: gnuplot2: Volume 11, Issue 65-79
  14.  
  15. #!/bin/sh
  16. # this is Part.14 (part 14 of a multipart archive)
  17. # do not concatenate these parts, unpack them in order with /bin/sh
  18. # file gnuplot/command.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" != 14; 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/command.c'
  34. else
  35. echo 'x - continuing file gnuplot/command.c'
  36. sed 's/^X//' << 'SHAR_EOF' >> 'gnuplot/command.c' &&
  37. X    
  38. X    Of course, the more interesting work is to move the y values of
  39. X    the x function to become the x values of the y function (checking
  40. X    the mins and maxs as we go along).
  41. */
  42. {
  43. X    struct curve_points *xp, *new_list, *yp = start_plot, *tmp, 
  44. X            *free_list, *free_head=NULL;
  45. X    int i, tlen, curve; 
  46. X    char *new_title;
  47. X    double lxmin, lxmax, temp;
  48. X
  49. X    if (autoscale_lx) {
  50. X        lxmin = VERYLARGE;
  51. X        lxmax = -VERYLARGE;
  52. X    } else {
  53. X        lxmin = xmin;
  54. X        lxmax = xmax;
  55. X    }
  56. X
  57. /* 
  58. X    Ok, go through all the plots and move FUNC types together.  Note: this
  59. X    originally was written to look for a NULL next pointer, but gnuplot 
  60. X    wants to be sticky in grabbing memory and the right number of items
  61. X    in the plot list is controlled by the plot_num variable.
  62. X
  63. X    Since gnuplot wants to do this sticky business, a free_list of 
  64. X    curve_points is kept and then tagged onto the end of the plot list as
  65. X    this seems more in the spirit of the original memory behavior than
  66. X    simply freeing the memory.  I'm personally not convinced this sort
  67. X    of concern is worth it since the time spent computing points seems
  68. X    to dominate any garbage collecting that might be saved here...
  69. */
  70. X    new_list = xp = start_plot; 
  71. X    yp = xp->next_cp;
  72. X   curve = 0;
  73. X    for (; curve < *plot_num; xp = xp->next_cp,yp = yp->next_cp,curve++) {
  74. X        if (xp->plot_type != FUNC) {
  75. X            continue;
  76. X        }
  77. X    /* Here's a FUNC parametric function defined as two parts. */
  78. X        --(*plot_num);
  79. X    /* 
  80. X        Go through all the points assigning the y's from xp to be the
  81. X        x's for yp.  Check max's and min's as you go.
  82. X    */
  83. X        for (i = 0; i < yp->p_count; ++i) {
  84. X        /* 
  85. X            Throw away excess xp points, mark excess yp points as OUTRANGE.
  86. X        */
  87. X            if (i > xp->p_count) {
  88. X                yp->points[i].type = OUTRANGE;
  89. X                continue;
  90. X            }
  91. X        /* 
  92. X            Just as we had to do when we computed y values--now check that
  93. X            x's (computed parametrically) are in the permitted ranges as well.
  94. X        */
  95. X            temp = xp->points[i].y;   /* New x value for yp function. */
  96. X            yp->points[i].x = temp;
  97. X        /* Handle undefined values differently from normal ranges. */
  98. X            if (xp->points[i].type == UNDEFINED)
  99. X                yp->points[i].type = xp->points[i].type;  
  100. X            if (autoscale_lx || polar
  101. X                       || inrange(temp, lxmin, lxmax)) {
  102. X               if (autoscale_lx && temp < lxmin) lxmin = temp;
  103. X                if (autoscale_lx && temp > lxmax) lxmax = temp;
  104. X            } else
  105. X            yp->points[i].type = OUTRANGE;  /* Due to x value. */
  106. X        }
  107. X   /* Ok, fix up the title to include both the xp and yp plots. */
  108. X        if (xp->title && xp->title[0] != '\0') {
  109. X            tlen = strlen (yp->title) + strlen (xp->title) + 3;
  110. X          new_title = alloc ((unsigned int) tlen, "string");
  111. X            strcpy (new_title, xp->title);  
  112. X            strcat (new_title, ", ");       /* + 2 */
  113. X            strcat (new_title, yp->title);  /* + 1 = + 3 */
  114. X            free (yp->title);
  115. X            yp->title = new_title;
  116. X        }
  117. X    /* Eliminate the first curve (xparam) and just use the second. */
  118. X        if (xp == start_plot) {
  119. X        /* Simply nip off the first element of the list. */
  120. X            new_list = first_plot = yp;
  121. X            xp = xp->next_cp;
  122. X            if (yp->next_cp != NULL)
  123. X                yp = yp->next_cp;
  124. X        /* Add start_plot to the free_list. */
  125. X            if (free_head == NULL) {
  126. X                free_list = free_head = start_plot;
  127. X                free_head->next_cp = NULL;
  128. X            } else {
  129. X                free_list->next_cp = start_plot;
  130. X                start_plot->next_cp = NULL;
  131. X                free_list = start_plot;
  132. X            }
  133. X        }
  134. X        else {
  135. X        /* Here, remove the xp node and replace it with the yp node. */
  136. X            tmp = xp;
  137. X        /* Pass over any data files that might have been in place. */
  138. X            while (new_list->next_cp && new_list->next_cp != xp) 
  139. X                new_list = new_list->next_cp;
  140. X            new_list->next_cp = yp;
  141. X            new_list = new_list->next_cp;
  142. X            xp = xp->next_cp;
  143. X            if (yp->next_cp != NULL)
  144. X                yp = yp->next_cp;
  145. X        /* Add tmp to the free_list. */
  146. X            tmp->next_cp = NULL;
  147. X            if (free_head == NULL) {
  148. X                free_list = free_head = tmp;
  149. X            } else {
  150. X                free_list->next_cp = tmp;
  151. X                free_list = tmp;
  152. X            }
  153. X        }
  154. X    }
  155. /* Ok, stick the free list at the end of the curve_points plot list. */
  156. X    while (new_list->next_cp != NULL)
  157. X        new_list = new_list->next_cp;
  158. X    new_list->next_cp = free_head;
  159. X
  160. /* Report the overall graph mins and maxs. */
  161. X    *x_min = lxmin;
  162. X    *x_max = lxmax;
  163. }
  164. X
  165. void parametric_3dfixup(start_plot, plot_num, x_min, x_max, y_min, y_max,
  166. X                                z_min, z_max)
  167. struct surface_points *start_plot;
  168. int *plot_num;
  169. double *x_min, *x_max, *y_min, *y_max, *z_min, *z_max;
  170. /*
  171. X    The hardest part of this routine is collapsing the FUNC plot types
  172. X   in the list (which are gauranteed to occur in (x,y,z) triplets while 
  173. X    preserving the non-FUNC type plots intact.  This means we have to
  174. X    work our way through various lists.  Examples (hand checked):
  175. X        start_plot:F1->F2->F3->NULL ==> F3->NULL
  176. X        start_plot:F1->F2->F3->F4->F5->F6->NULL ==> F3->F6->NULL
  177. X        start_plot:F1->F2->F3->D1->D2->F4->F5->F6->D3->NULL ==>
  178. X                        F3->D1->D2->F6->D3->NULL
  179. */
  180. {
  181. X    struct surface_points *xp, *yp, *zp, *new_list, *tmp, 
  182. X            *free_list, *free_head=NULL;
  183. X    struct iso_curve *icrvs, *xicrvs, *yicrvs, *zicrvs;
  184. X    int i, tlen, surface;
  185. X    char *new_title;
  186. X    double lxmin, lxmax, lymin, lymax, lzmin, lzmax, temp;
  187. X
  188. X    if (autoscale_lx) {
  189. X        lxmin = VERYLARGE;
  190. X        lxmax = -VERYLARGE;
  191. X    } else {
  192. X        lxmin = xmin;
  193. X        lxmax = xmax;
  194. X    }
  195. X
  196. X    if (autoscale_ly) {
  197. X        lymin = VERYLARGE;
  198. X        lymax = -VERYLARGE;
  199. X    } else {
  200. X        lymin = ymin;
  201. X        lymax = ymax;
  202. X    }
  203. X
  204. X    if (autoscale_lz) {
  205. X        lzmin = VERYLARGE;
  206. X        lzmax = -VERYLARGE;
  207. X    } else {
  208. X        lzmin = zmin;
  209. X        lzmax = zmax;
  210. X    }
  211. X
  212. /* 
  213. X    Ok, go through all the plots and move FUNC3D types together.  Note:
  214. X    this originally was written to look for a NULL next pointer, but
  215. X    gnuplot wants to be sticky in grabbing memory and the right number
  216. X    of items in the plot list is controlled by the plot_num variable.
  217. X
  218. X    Since gnuplot wants to do this sticky business, a free_list of 
  219. X    surface_points is kept and then tagged onto the end of the plot list as
  220. X    this seems more in the spirit of the original memory behavior than
  221. X    simply freeing the memory.  I'm personally not convinced this sort
  222. X    of concern is worth it since the time spent computing points seems
  223. X    to dominate any garbage collecting that might be saved here...
  224. */
  225. X    new_list = xp = start_plot; 
  226. X    for (surface = 0; surface < *plot_num; surface++) {
  227. X        if (xp->plot_type != FUNC3D) {
  228. X            icrvs = xp->iso_crvs;
  229. X
  230. X            while ( icrvs ) {
  231. X                struct coordinate *points = icrvs->points;
  232. X
  233. X                for (i = 0; i < icrvs->p_count; ++i) {
  234. X                    if (lxmin > points[i].x)
  235. X                        lxmin = points[i].x;
  236. X                    if (lxmax < points[i].x)
  237. X                        lxmax = points[i].x;
  238. X                    if (lymin > points[i].y)
  239. X                        lymin = points[i].y;
  240. X                    if (lymax < points[i].y)
  241. X                        lymax = points[i].y;
  242. X                    if (lzmin > points[i].z)
  243. X                        lzmin = points[i].z;
  244. X                    if (lzmax < points[i].z)
  245. X                        lzmax = points[i].z;
  246. X                }
  247. X
  248. X                icrvs = icrvs->next;
  249. X            }
  250. X            xp = xp->next_sp;
  251. X            continue;
  252. X        }
  253. X
  254. X        yp = xp->next_sp;
  255. X        zp = yp->next_sp;
  256. X
  257. X    /* Here's a FUNC3D parametric function defined as three parts. */
  258. X        (*plot_num) -= 2;
  259. X    /* 
  260. X        Go through all the points and assign the x's and y's from xp
  261. X        and yp to zp.  Check max's and min's as you go.
  262. X    */
  263. X        xicrvs = xp->iso_crvs;
  264. X        yicrvs = yp->iso_crvs;
  265. X        zicrvs = zp->iso_crvs;
  266. X        while ( zicrvs ) {
  267. X            struct coordinate *xpoints = xicrvs->points,
  268. X                     *ypoints = yicrvs->points,
  269. X                     *zpoints = zicrvs->points;
  270. X            for (i = 0; i < zicrvs->p_count; ++i) {
  271. X                zpoints[i].x = xpoints[i].z;
  272. X                zpoints[i].y = ypoints[i].z;
  273. X
  274. X                if (lxmin > zpoints[i].x) lxmin = zpoints[i].x;
  275. X                if (lxmax < zpoints[i].x) lxmax = zpoints[i].x;
  276. X                if (lymin > zpoints[i].y) lymin = zpoints[i].y;
  277. X                if (lymax < zpoints[i].y) lymax = zpoints[i].y;
  278. X                if (lzmin > zpoints[i].z) lzmin = zpoints[i].z;
  279. X                if (lzmax < zpoints[i].z) lzmax = zpoints[i].z;
  280. X            }
  281. X            xicrvs = xicrvs->next;
  282. X            yicrvs = yicrvs->next;
  283. X            zicrvs = zicrvs->next;
  284. X        }
  285. X
  286. X    /* Ok, fix up the title to include xp and yp plots. */
  287. X        if ((xp->title && xp->title[0] != '\0') ||
  288. X            (yp->title && yp->title[0] != '\0')) {
  289. X            tlen = (xp->title ? strlen(xp->title) : 0) +
  290. X                   (yp->title ? strlen(yp->title) : 0) +
  291. X                   (zp->title ? strlen(zp->title) : 0) + 5;
  292. X            new_title = alloc ((unsigned int) tlen, "string");
  293. X            new_title[0] = 0;
  294. X            if (xp->title) {
  295. X                strcat(new_title, xp->title);
  296. X                strcat(new_title, ", ");       /* + 2 */
  297. X            }
  298. X            if (yp->title) {
  299. X                strcat(new_title, yp->title);
  300. X                strcat(new_title, ", ");       /* + 2 */
  301. X            }
  302. X            if (zp->title) {
  303. X                strcat(new_title, zp->title);
  304. X            }
  305. X            free (zp->title);
  306. X            zp->title = new_title;
  307. X        }
  308. X
  309. X    /* Eliminate the first two surfaces (xp and yp) and just use the third. */
  310. X        if (xp == start_plot) {
  311. X        /* Simply nip off the first two elements of the list. */
  312. X            new_list = first_3dplot = zp;
  313. X            xp = zp->next_sp;
  314. X        /* Add xp and yp to the free_list. */
  315. X            if (free_head == NULL) {
  316. X                free_head = start_plot;
  317. X            } else {
  318. X                free_list->next_sp = start_plot;
  319. X            }
  320. X            free_list = start_plot->next_sp;
  321. X            free_list->next_sp = NULL;
  322. X        }
  323. X        else {
  324. X        /* Here, remove the xp,yp nodes and replace them with the zp node. */
  325. X            tmp = xp;
  326. X        /* Pass over any data files that might have been in place. */
  327. X            while (new_list->next_sp && new_list->next_sp != xp)
  328. X                new_list = new_list->next_sp;
  329. X            new_list->next_sp = zp;
  330. X            new_list = zp;
  331. X            xp = zp->next_sp;
  332. X        /* Add tmp to the free_list. */
  333. X            if (free_head == NULL) {
  334. X                free_head = tmp;
  335. X            } else {
  336. X                free_list->next_sp = tmp;
  337. X            }
  338. X            free_list = tmp->next_sp;
  339. X            free_list->next_sp = NULL;
  340. X        }
  341. X    }
  342. /* Ok, stick the free list at the end of the surface_points plot list. */
  343. X    while (new_list->next_sp != NULL)
  344. X        new_list = new_list->next_sp;
  345. X    new_list->next_sp = free_head;
  346. X
  347. /* Report the overall graph mins and maxs. */
  348. X    if (autoscale_lx) {
  349. X        *x_min = (log_x ? pow(10.0, lxmin) : lxmin);
  350. X        *x_max = (log_x ? pow(10.0, lxmax) : lxmax);
  351. X    }
  352. X    else {
  353. X        *x_min = xmin;
  354. X        *x_max = xmax;
  355. X    }
  356. X    if (autoscale_ly) {
  357. X        *y_min = (log_y ? pow(10.0, lymin) : lymin);
  358. X        *y_max = (log_y ? pow(10.0, lymax) : lymax);
  359. X    }
  360. X    else {
  361. X        *y_min = ymin;
  362. X        *y_max = ymax;
  363. X    }
  364. X    if (autoscale_lz) {
  365. X        *z_min = (log_z ? pow(10.0, lzmin) : lzmin);
  366. X        *z_max = (log_z ? pow(10.0, lzmax) : lzmax);
  367. X    }
  368. X    else {
  369. X        *z_min = zmin;
  370. X        *z_max = zmax;
  371. X    }
  372. }
  373. X
  374. #ifdef AMIGA_LC_5_1
  375. void sleep(delay)
  376. unsigned int delay;
  377. {
  378. X  Delay(50 * delay);
  379. }
  380. #endif
  381. X
  382. #ifdef AMIGA_AC_5
  383. void sleep(delay)
  384. unsigned int delay;
  385. {
  386. unsigned long time_is_up;
  387. X    time_is_up = time(NULL) + (unsigned long) delay; 
  388. X    while (time(NULL)<time_is_up)
  389. X        /* wait */ ;
  390. }
  391. #endif
  392. X
  393. #ifdef MSDOS
  394. #ifndef __TURBOC__    /* Turbo C already has sleep() */
  395. #ifndef __ZTC__     /* ZTC already has usleep() */
  396. /* kludge to provide sleep() for msc 5.1 */
  397. void sleep(delay)
  398. unsigned int delay;
  399. {
  400. unsigned long time_is_up;
  401. X    time_is_up = time(NULL) + (unsigned long) delay; 
  402. X    while (time(NULL)<time_is_up)
  403. X        /* wait */ ;
  404. }
  405. #endif /* not ZTC */
  406. #endif /* not TURBOC */
  407. #endif /* MSDOS */
  408. X
  409. X
  410. /* Support for input, shell, and help for various systems */
  411. X
  412. #ifdef vms
  413. X
  414. #include <descrip.h>
  415. #include <rmsdef.h>
  416. #include <errno.h>
  417. #include <smgdef.h>
  418. #include <smgmsg.h>
  419. X
  420. extern lib$get_input(), lib$put_output();
  421. extern smg$read_composed_line();
  422. X
  423. int vms_len;
  424. X
  425. unsigned int status[2] = {1, 0};
  426. X
  427. static char help[MAX_LINE_LEN+1] = "gnuplot";
  428. X
  429. $DESCRIPTOR(prompt_desc,PROMPT);
  430. $DESCRIPTOR(line_desc,input_line);
  431. X
  432. $DESCRIPTOR(help_desc,help);
  433. $DESCRIPTOR(helpfile_desc,"GNUPLOT$HELP");
  434. X
  435. X
  436. read_line(prompt)
  437. char *prompt;
  438. {
  439. X    int more, start=0;
  440. X    char expand_prompt[40];
  441. X
  442. X    prompt_desc.dsc$w_length = strlen (prompt);
  443. X    prompt_desc.dsc$a_pointer = prompt;
  444. X    (void) strcpy (expand_prompt, "_");
  445. X    (void) strncat (expand_prompt, prompt, 38);
  446. X    do {
  447. X        line_desc.dsc$w_length = MAX_LINE_LEN - start;
  448. X        line_desc.dsc$a_pointer = &input_line[start];
  449. X        switch(status[1] = smg$read_composed_line(&vms_vkid,0,&line_desc, &prompt_desc, &vms_len)){
  450. X          case SMG$_EOF:
  451. X          done(IO_SUCCESS);    /* ^Z isn't really an error */
  452. X          break;
  453. X          case RMS$_TNS:    /* didn't press return in time *
  454. X                           /
  455. X                           vms_len--; /* skip the last character */
  456. X          break;            /* and parse anyway */
  457. X          case RMS$_BES:    /* Bad Escape Sequence */
  458. X          case RMS$_PES:    /* Partial Escape Sequence */
  459. X          sys$putmsg(status);
  460. X          vms_len = 0;        /* ignore the line */
  461. X          break;
  462. X          case SS$_NORMAL:
  463. X          break;            /* everything's fine */
  464. X          default:
  465. X          done(status[1]);    /* give the error message */
  466. X        }
  467. X        start += vms_len;
  468. X        input_line[start] = '\0';
  469. X       inline_num++;
  470. X        if (input_line[start-1] == '\\') {
  471. X          /* Allow for a continuation line. */
  472. X          prompt_desc.dsc$w_length = strlen (expand_prompt);
  473. X          prompt_desc.dsc$a_pointer = expand_prompt;
  474. X          more = 1;
  475. X          --start;
  476. X        }
  477. X        else {
  478. X          line_desc.dsc$w_length = strlen(input_line);
  479. X          line_desc.dsc$a_pointer = input_line;
  480. X          more = 0;
  481. X        }
  482. X    } while (more);
  483. }
  484. X
  485. X
  486. do_help()
  487. {
  488. X    help_desc.dsc$w_length = strlen(help);
  489. X    if ((vaxc$errno = lbr$output_help(lib$put_output,0,&help_desc,
  490. X        &helpfile_desc,0,lib$get_input)) != SS$_NORMAL)
  491. X            os_error("can't open GNUPLOT$HELP");
  492. }
  493. X
  494. X
  495. do_shell()
  496. {
  497. X    if ((vaxc$errno = lib$spawn()) != SS$_NORMAL) {
  498. X        os_error("spawn error",NO_CARET);
  499. X    }
  500. }
  501. X
  502. X
  503. do_system()
  504. {
  505. X    input_line[0] = ' ';    /* an embarrassment, but... */
  506. X
  507. X    if ((vaxc$errno = lib$spawn(&line_desc)) != SS$_NORMAL)
  508. X        os_error("spawn error",NO_CARET);
  509. X
  510. X    (void) putc('\n',stderr);
  511. }
  512. X
  513. #else /* vms */
  514. X
  515. /* do_help: (not VMS, although it would work)
  516. X * Give help to the user. 
  517. X * It parses the command line into helpbuf and supplies help for that 
  518. X * string. Then, if there are subtopics available for that key,
  519. X * it prompts the user with this string. If more input is
  520. X * given, do_help is called recursively, with the argument the index of 
  521. X * null character in the string. Thus a more specific help can be 
  522. X * supplied. This can be done repeatedly. 
  523. X * If null input is given, the function returns, effecting a
  524. X * backward climb up the tree.
  525. X * David Kotz (David.Kotz@Dartmouth.edu) 10/89
  526. X */
  527. do_help()
  528. {
  529. X    static char *helpbuf = NULL;
  530. X    static char *prompt = NULL;
  531. X    int base;                /* index of first char AFTER help string */
  532. X    int len;                /* length of current help string */
  533. X    BOOLEAN more_help;
  534. X    BOOLEAN only;            /* TRUE if only printing subtopics */
  535. X    int subtopics;            /* 0 if no subtopics for this topic */
  536. X    int start;                /* starting token of help string */
  537. X    char *help_ptr;            /* name of help file */
  538. X
  539. X    if ( (help_ptr = getenv("GNUHELP")) == (char *)NULL )
  540. X        /* if can't find environment variable then just use HELPFILE */
  541. X        help_ptr = HELPFILE;
  542. X
  543. X    /* Since MSDOS DGROUP segment is being overflowed we can not allow such  */
  544. X    /* huge static variables (1k each). Instead we dynamically allocate them */
  545. X    /* on the first call to this function...                     */
  546. X    if (helpbuf == NULL) {
  547. X    helpbuf = alloc(MAX_LINE_LEN, "help buffer");
  548. X    prompt = alloc(MAX_LINE_LEN, "help prompt");
  549. X    helpbuf[0] = prompt[0] = 0;
  550. X    }
  551. X
  552. X    len = base = strlen(helpbuf);
  553. X
  554. X    /* find the end of the help command */
  555. X    for (start = c_token; !(END_OF_COMMAND); c_token++)
  556. X     ;
  557. X    /* copy new help input into helpbuf */
  558. X    if (len > 0)
  559. X     helpbuf[len++] = ' ';    /* add a space */
  560. X    capture(helpbuf+len, start, c_token-1);
  561. X    squash_spaces(helpbuf+base); /* only bother with new stuff */
  562. X    lower_case(helpbuf+base); /* only bother with new stuff */
  563. X    len = strlen(helpbuf);
  564. X
  565. X    /* now, a lone ? will print subtopics only */
  566. X    if (strcmp(helpbuf + (base ? base+1 : 0), "?") == 0) {
  567. X       /* subtopics only */
  568. X       subtopics = 1;
  569. X       only = TRUE;
  570. X       helpbuf[base] = '\0';    /* cut off question mark */
  571. X    } else {
  572. X       /* normal help request */
  573. X       subtopics = 0;
  574. X       only = FALSE;
  575. X    }
  576. X
  577. X    switch (help(helpbuf, help_ptr, &subtopics)) {
  578. X       case H_FOUND: {
  579. X          /* already printed the help info */
  580. X          /* subtopics now is true if there were any subtopics */
  581. X          screen_ok = FALSE;
  582. X    
  583. X          do {
  584. X             if (subtopics && !only) {
  585. X                /* prompt for subtopic with current help string */
  586. X                if (len > 0)
  587. X                  (void) sprintf(prompt, "Subtopic of %s: ", helpbuf);
  588. X                else
  589. X                  (void) strcpy(prompt, "Help topic: ");
  590. X                read_line(prompt);
  591. X                num_tokens = scanner(input_line);
  592. X                c_token = 0;
  593. X                more_help = !(END_OF_COMMAND);
  594. X                if (more_help)
  595. X                  /* base for next level is all of current helpbuf */
  596. X                  do_help();
  597. X             } else 
  598. X               more_help = FALSE;
  599. X          } while(more_help);
  600. X    
  601. X          break;
  602. X       }
  603. X       case H_NOTFOUND: {
  604. X          printf("Sorry, no help for '%s'\n", helpbuf);
  605. X          break;
  606. X       }
  607. X       case H_ERROR: {
  608. X          perror(help_ptr);
  609. X          break;
  610. X       }
  611. X       default: {        /* defensive programming */
  612. X          int_error("Impossible case in switch\n", NO_CARET);
  613. X          /* NOTREACHED */
  614. X       }
  615. X    }
  616. X    
  617. X    helpbuf[base] = '\0';    /* cut it off where we started */
  618. }
  619. X
  620. #ifdef AMIGA_AC_5
  621. char strg0[256];
  622. #endif
  623. X
  624. do_system()
  625. {
  626. #ifdef AMIGA_AC_5
  627. X   char *parms[80];
  628. X   void getparms();
  629. X
  630. X   getparms(input_line+1,parms);
  631. X   if(fexecv(parms[0],parms) < 0)
  632. #else
  633. X   if (system(input_line + 1))
  634. #endif
  635. X      os_error("system() failed",NO_CARET);
  636. }
  637. X
  638. #ifdef AMIGA_AC_5
  639. X
  640. /******************************************************************************/
  641. /*                                                                            */
  642. /*  Parses the command string (for fexecv use) and  converts the first token  */
  643. /*     to lower case                                                          */
  644. /*                                                                            */
  645. /******************************************************************************/
  646. X
  647. void getparms(command,parms)
  648. X   char *command;
  649. X   char **parms;
  650. X   {
  651. X   register int i = 0;                         /* A bunch of indices          */
  652. X   register int j = 0;
  653. X   register int k = 0;
  654. X
  655. X   while(*(command+j) != '\0')                 /* Loop on string characters   */
  656. X      {
  657. X      parms[k++] = strg0+i;
  658. X      while(*(command+j) == ' ') ++j;
  659. X      while(*(command+j) != ' ' && *(command+j) != '\0')
  660. X         {
  661. X         if(*(command+j) == '"')               /* Get quoted string           */
  662. X            for(*(strg0+(i++)) = *(command+(j++));
  663. X                *(command+j)  != '"';
  664. X                *(strg0+(i++)) = *(command+(j++)));
  665. X         *(strg0+(i++)) = *(command+(j++));
  666. X         }
  667. X      *(strg0+(i++)) = '\0';                   /* NUL terminate every token   */
  668. X      }
  669. X   parms[k] = '\0';
  670. X
  671. X   for(k=strlen(strg0)-1; k>=0; --k)           /* Convert to lower case       */
  672. X      *(strg0+k)>='A' && *(strg0+k)<='Z'? *(strg0+k)|=32: *(strg0+k);
  673. X   }
  674. X
  675. #endif /* AMIGA_AC_5 */
  676. X
  677. #ifdef READLINE
  678. char *
  679. rlgets(s, n, prompt)
  680. char *s;
  681. int n;
  682. char *prompt;
  683. {
  684. X      char *readline();
  685. X      static char *line = (char *)NULL;
  686. X
  687. X      /* If we already have a line, first free it */
  688. X      if(line != (char *)NULL) 
  689. X              free(line);
  690. X
  691. X      line = readline((interactive)?prompt:"");
  692. X
  693. X      /* If it's not an EOF */
  694. X      if(line) {
  695. X      if (*line)
  696. X              add_history(line);
  697. X      strncpy(s, line, n);
  698. X      return s;
  699. X      }
  700. X
  701. X      return line;
  702. }
  703. #endif /* READLINE */
  704. X
  705. #ifdef MSDOS
  706. X
  707. #ifdef __TURBOC__
  708. /* cgets implemented using dos functions */
  709. /* Maurice Castro 22/5/91 */
  710. char *doscgets(s)
  711. char *s;
  712. {
  713. X   long datseg;
  714. X
  715. X   /* protect and preserve segments - call dos to do the dirty work */
  716. X   datseg = _DS;
  717. X
  718. X   _DX = FP_OFF(s);
  719. X   _DS = FP_SEG(s);
  720. X   _AH = 0x0A;
  721. X   geninterrupt(33);
  722. X   _DS = datseg;
  723. X
  724. X   /* check for a carriage return and then clobber it with a null */
  725. X   if (s[s[1]+2] == '\r') 
  726. X      s[s[1]+2] = 0;
  727. X
  728. X   /* return the input string */
  729. X   return(&(s[2]));
  730. X   }
  731. #endif /* __TURBOC__ */
  732. X
  733. X
  734. read_line(prompt)
  735. X    char *prompt;
  736. {
  737. X    register int i;
  738. X    int start = 0, ilen = 0;
  739. X    BOOLEAN more;
  740. X    int last;
  741. X    char *p, *crnt_prompt = prompt;
  742. X    
  743. #ifndef __ZTC__
  744. X    if (interactive) { /* if interactive use console IO so CED will work */
  745. #ifndef READLINE
  746. X        cputs(prompt);
  747. #endif /* READLINE */
  748. X        do {
  749. X           ilen = MAX_LINE_LEN-start-1;
  750. X           input_line[start] = ilen > 126 ? 126 : ilen;
  751. #ifdef READLINE
  752. X           input_line[start+2] = 0;
  753. X           (void) rlgets(&(input_line[start+2]), ilen, crnt_prompt );
  754. X           if (p = strchr(&(input_line[start+2]), '\r')) *p = 0;
  755. X           if (p = strchr(&(input_line[start+2]), '\n')) *p = 0;
  756. X           input_line[start+1] = strlen(&(input_line[start+2]));
  757. #else /* READLINE */
  758. #ifdef __TURBOC__
  759. X           (void) doscgets(&(input_line[start]));
  760. #else /* __TURBOC__ */
  761. X           (void) cgets(&(input_line[start]));
  762. #endif /* __TURBOC__ */
  763. X           (void) putc('\n',stderr);
  764. #endif /* READLINE */
  765. X           if (input_line[start+2] == 26) {
  766. X              /* end-of-file */
  767. X              (void) putc('\n',stderr);
  768. X              input_line[start] = '\0';
  769. X              inline_num++;
  770. X              if (start > 0)    /* don't quit yet - process what we have */
  771. X                more = FALSE;
  772. X              else {
  773. X                 (void) putc('\n',stderr);
  774. X                 done(IO_SUCCESS);
  775. X                 /* NOTREACHED */
  776. X              }
  777. X           } else {
  778. X              /* normal line input */
  779. X              register i = start;
  780. X              while ( (input_line[i] = input_line[i+2]) != (char)NULL )
  781. X                i++;        /* yuck!  move everything down two characters */
  782. X
  783. X              inline_num++;
  784. X              last = strlen(input_line) - 1;
  785. X              if (last + 1 >= MAX_LINE_LEN)
  786. X                int_error("Input line too long",NO_CARET);
  787. X                     
  788. X              if (input_line[last] == '\\') { /* line continuation */
  789. X                 start = last;
  790. X                 more = TRUE;
  791. X              } else
  792. X                more = FALSE;
  793. X           }
  794. #ifndef READLINE
  795. X           if (more)
  796. X            cputs("> ");
  797. #else
  798. X           crnt_prompt = "> ";
  799. #endif /* READLINE */
  800. X        } while(more);
  801. X    }
  802. X    else { /* not interactive */
  803. #endif /* not ZTC */
  804. X        if (interactive)
  805. X         fputs(prompt,stderr);
  806. X        do {
  807. X           /* grab some input */
  808. X           if ( fgets(&(input_line[start]), MAX_LINE_LEN - start, stdin) 
  809. X                    == (char *)NULL ) {
  810. X              /* end-of-file */
  811. X              if (interactive)
  812. X                (void) putc('\n',stderr);
  813. X              input_line[start] = '\0';
  814. X              inline_num++;
  815. X              if (start > 0)    /* don't quit yet - process what we have */
  816. X                more = FALSE;
  817. X              else
  818. X                done(IO_SUCCESS); /* no return */
  819. X           } else {
  820. X              /* normal line input */
  821. X              last = strlen(input_line) - 1;
  822. X              if (input_line[last] == '\n') { /* remove any newline */
  823. X                 input_line[last] = '\0';
  824. X                 /* Watch out that we don't backup beyond 0 (1-1-1) */
  825. X                 if (last > 0) --last;
  826. X                 inline_num++;
  827. X              } else if (last+1 >= MAX_LINE_LEN)
  828. X                int_error("Input line too long",NO_CARET);
  829. X                     
  830. X              if (input_line[last] == '\\') { /* line continuation */
  831. X                 start = last;
  832. X                 more = TRUE;
  833. X              } else
  834. X                more = FALSE;
  835. X           }
  836. X            if (more && interactive)
  837. X            fputs("> ", stderr);
  838. X        } while(more);
  839. #ifndef __ZTC
  840. X    }
  841. #endif
  842. }
  843. X
  844. X
  845. do_shell()
  846. {
  847. register char *comspec;
  848. X    if ((comspec = getenv("COMSPEC")) == (char *)NULL)
  849. X        comspec = "\command.com";
  850. X    if (spawnl(P_WAIT,comspec,NULL) == -1)
  851. X        os_error("unable to spawn shell",NO_CARET);
  852. }
  853. X
  854. #else /* MSDOS */
  855. X        /* plain old Unix */
  856. X
  857. read_line(prompt)
  858. X    char *prompt;
  859. {
  860. X    int start = 0;
  861. X    BOOLEAN more = FALSE;
  862. X    int last = 0;
  863. X
  864. #ifndef READLINE
  865. X    if (interactive)
  866. X     fputs(prompt,stderr);
  867. #endif /* READLINE */
  868. X    do {
  869. X       /* grab some input */
  870. #ifdef READLINE
  871. X     if (((interactive)
  872. X         ?rlgets(&(input_line[start]), MAX_LINE_LEN - start,
  873. X                ((more)?"> ":prompt))
  874. X         :fgets(&(input_line[start]), MAX_LINE_LEN - start, stdin))
  875. X                              == (char *)NULL ) {
  876. #else
  877. X       if ( fgets(&(input_line[start]), MAX_LINE_LEN - start, stdin) 
  878. X                == (char *)NULL ) {
  879. #endif /* READLINE */
  880. X          /* end-of-file */
  881. X          if (interactive)
  882. X            (void) putc('\n',stderr);
  883. X          input_line[start] = '\0';
  884. X          inline_num++;
  885. X          if (start > 0)    /* don't quit yet - process what we have */
  886. X            more = FALSE;
  887. X          else
  888. X            done(IO_SUCCESS); /* no return */
  889. X       } else {
  890. X          /* normal line input */
  891. X          last = strlen(input_line) - 1;
  892. X          if (input_line[last] == '\n') { /* remove any newline */
  893. X             input_line[last] = '\0';
  894. X                /* Watch out that we don't backup beyond 0 (1-1-1) */
  895. X             if (last > 0) --last;
  896. X             inline_num++;
  897. X          } else if (last+1 >= MAX_LINE_LEN)
  898. X            int_error("Input line too long",NO_CARET);
  899. X                 
  900. X          if (input_line[last] == '\\') { /* line continuation */
  901. X             start = last;
  902. X             more = TRUE;
  903. X          } else
  904. X            more = FALSE;
  905. X       }
  906. #ifndef READLINE
  907. X        if (more && interactive)
  908. X        fputs("> ", stderr);
  909. #endif
  910. X    } while(more);
  911. }
  912. X
  913. #ifdef VFORK
  914. X
  915. do_shell()
  916. {
  917. register char *shell;
  918. register int p;
  919. static int execstat;
  920. X    if (!(shell = getenv("SHELL")))
  921. X        shell = SHELL;
  922. #ifdef AMIGA_AC_5
  923. X    execstat = fexecl(shell,shell,NULL);
  924. #else
  925. X    if ((p = vfork()) == 0) {
  926. X        execstat = execl(shell,shell,NULL);
  927. X        _exit(1);
  928. X    } else if (p == -1)
  929. X        os_error("vfork failed",c_token);
  930. X    else
  931. X        while (wait(NULL) != p)
  932. #endif
  933. X            ;
  934. X    if (execstat == -1)
  935. X        os_error("shell exec failed",c_token);
  936. X    (void) putc('\n',stderr);
  937. }
  938. #else /* VFORK */
  939. X
  940. #ifdef AMIGA_LC_5_1
  941. do_shell()
  942. {
  943. register char *shell;
  944. X    if (!(shell = getenv("SHELL")))
  945. X        shell = SHELL;
  946. X
  947. X    if (system(shell))
  948. X        os_error("system() failed",NO_CARET);
  949. X
  950. X    (void) putc('\n',stderr);
  951. }
  952. #else /* AMIGA_LC_5_1 */
  953. X
  954. #define EXEC "exec "
  955. do_shell()
  956. {
  957. static char exec[100] = EXEC;
  958. register char *shell;
  959. X    if (!(shell = getenv("SHELL")))
  960. X        shell = SHELL;
  961. X
  962. X    if (system(strncpy(&exec[sizeof(EXEC)-1],shell,
  963. X        sizeof(exec)-sizeof(EXEC)-1)))
  964. X        os_error("system() failed",NO_CARET);
  965. X
  966. X    (void) putc('\n',stderr);
  967. }
  968. #endif /* AMIGA_LC_5_1 */
  969. #endif /* VFORK */
  970. #endif /* MSDOS */
  971. #endif /* vms */
  972. SHAR_EOF
  973. echo 'File gnuplot/command.c is complete' &&
  974. chmod 0644 gnuplot/command.c ||
  975. echo 'restore of gnuplot/command.c failed'
  976. Wc_c="`wc -c < 'gnuplot/command.c'`"
  977. test 85435 -eq "$Wc_c" ||
  978.     echo 'gnuplot/command.c: original size 85435, current size' "$Wc_c"
  979. rm -f _shar_wnt_.tmp
  980. fi
  981. # ============= gnuplot/lineproc.mac ==============
  982. if test -f 'gnuplot/lineproc.mac' -a X"$1" != X"-c"; then
  983.     echo 'x - skipping gnuplot/lineproc.mac (File already exists)'
  984.     rm -f _shar_wnt_.tmp
  985. else
  986. > _shar_wnt_.tmp
  987. echo 'x - extracting gnuplot/lineproc.mac (Text)'
  988. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/lineproc.mac' &&
  989. ; lineproc.mac
  990. ; MASM macro definition for Bresenham line-drawing routine
  991. ; Colin Kelley
  992. ; January 13, 1987
  993. X
  994. X
  995. INCAX    equ 40h            ; for Self-Modifying Code
  996. INCBX    equ 43h
  997. DECAX    equ 48h
  998. DECBX    equ 4bh
  999. X
  1000. ; usage:
  1001. ;   lineproc linename, pixelname
  1002. ;
  1003. ; where linemane is the name you want for the proc, and pixelname is the
  1004. ;   name of the routine that linename is to call to set pixels
  1005. ;
  1006. X
  1007. lineproc macro linename, pixelname
  1008. beginproc linename
  1009. X
  1010. X    push bp
  1011. X    mov bp,sp
  1012. X    push si
  1013. X    push di
  1014. X    mov ax,[bp+X]        ; x1
  1015. X    mov bx,[bp+X+2]        ; y1
  1016. X    mov cx,[bp+X+4]        ; x2
  1017. X    mov si,[bp+X+6]        ; y2
  1018. X
  1019. X    cmp ax,cx        ; x1,x2
  1020. X    jne i19
  1021. X    cmp bx,si        ; y1,y2
  1022. X    jne i19
  1023. X
  1024. X    call pixelname
  1025. X
  1026. X    jmp i28
  1027. i19:
  1028. X    mov dx,ax        ; dx,x1
  1029. X    sub dx,cx        ; x2
  1030. X    jnc noabsx
  1031. X    neg dx
  1032. noabsx:
  1033. X    mov di,bx        ; dy,y1
  1034. X    sub di,si        ; y2
  1035. X    jnc noabsy
  1036. X    neg di            ; dy
  1037. noabsy:
  1038. X    cmp dx,di        ; dx,dy
  1039. X    jb i21            ; go iterate y's
  1040. ;
  1041. ; iterate x's
  1042. ;
  1043. X    cmp bx,si        ; y1,y2
  1044. X    jb forwardy
  1045. X    mov byte ptr cs:yinc1,DECBX
  1046. X    jmp short i22
  1047. forwardy:
  1048. X    mov byte ptr cs:yinc1,INCBX
  1049. i22:
  1050. X    cmp ax,cx        ; x1,x2
  1051. X    jae l20004
  1052. X    mov byte ptr cs:xinc1,INCAX
  1053. X    jmp short l20005
  1054. l20004:
  1055. X    mov byte ptr cs:xinc1,DECAX
  1056. l20005:
  1057. X    mov bp,dx        ; sum,dx
  1058. X    shr bp,1        ; sum
  1059. d23:
  1060. X    cmp ax,cx        ; x1,x2
  1061. X    je i28            ; done
  1062. xinc1:    inc ax            ; may become inc or dec
  1063. X    add bp,di        ; sum,dy
  1064. X    cmp bp,dx
  1065. X    jb i27
  1066. X    sub bp,dx        ; sum,dx
  1067. yinc1:    inc bx            ; may become inc or dec
  1068. i27:
  1069. X    call pixelname
  1070. X    jmp short d23
  1071. X
  1072. ;
  1073. ; else iterate y's
  1074. ;
  1075. i21:
  1076. X    cmp ax,cx        ; x1,x2
  1077. X    jae l20006
  1078. X    mov byte ptr cs:xinc2,INCAX
  1079. X    jmp short l20007
  1080. l20006:
  1081. X    mov byte ptr cs:xinc2,DECAX
  1082. l20007:
  1083. X    cmp bx,si        ; y1,y2
  1084. X    jb forwardy2
  1085. X    mov byte ptr cs:yinc2,DECBX
  1086. X    jmp short i29
  1087. forwardy2:
  1088. X    mov byte ptr cs:yinc2,INCBX
  1089. i29:
  1090. X    mov bp,di        ; sum,dy
  1091. X    shr bp,1        ; sum,1
  1092. d30:
  1093. X    cmp bx,si        ; y1,y2
  1094. X    je i28
  1095. yinc2:    inc bx            ; may become inc or dec
  1096. X    add bp,dx        ; sum,dx
  1097. X    cmp bp,di        ; sum,dy
  1098. X    jb i34
  1099. X    sub bp,di        ; sum,dy
  1100. xinc2:    inc ax            ; may become inc or dec
  1101. i34:
  1102. X    call near ptr pixelname
  1103. X    jmp short d30
  1104. ;
  1105. ; clean up and exit
  1106. ;
  1107. i28:
  1108. X    pop di
  1109. X    pop si
  1110. X    pop bp
  1111. X    ret
  1112. X
  1113. linename endp
  1114. X    endm
  1115. SHAR_EOF
  1116. chmod 0666 gnuplot/lineproc.mac ||
  1117. echo 'restore of gnuplot/lineproc.mac failed'
  1118. Wc_c="`wc -c < 'gnuplot/lineproc.mac'`"
  1119. test 1980 -eq "$Wc_c" ||
  1120.     echo 'gnuplot/lineproc.mac: original size 1980, current size' "$Wc_c"
  1121. rm -f _shar_wnt_.tmp
  1122. fi
  1123. # ============= gnuplot/linkopt.msc ==============
  1124. if test -f 'gnuplot/linkopt.msc' -a X"$1" != X"-c"; then
  1125.     echo 'x - skipping gnuplot/linkopt.msc (File already exists)'
  1126.     rm -f _shar_wnt_.tmp
  1127. else
  1128. > _shar_wnt_.tmp
  1129. echo 'x - extracting gnuplot/linkopt.msc (Text)'
  1130. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/linkopt.msc' &&
  1131. pcgraph+hrcgraph+corgraph+bitmap+term+graphics+graph3d+contour+
  1132. plot+setshow+command+help+internal+misc+
  1133. parse+eval+scanner+standard+util+version
  1134. gnuplot
  1135. nul;
  1136. SHAR_EOF
  1137. chmod 0644 gnuplot/linkopt.msc ||
  1138. echo 'restore of gnuplot/linkopt.msc failed'
  1139. Wc_c="`wc -c < 'gnuplot/linkopt.msc'`"
  1140. test 159 -eq "$Wc_c" ||
  1141.     echo 'gnuplot/linkopt.msc: original size 159, current size' "$Wc_c"
  1142. rm -f _shar_wnt_.tmp
  1143. fi
  1144. # ============= gnuplot/makefile.tc ==============
  1145. if test -f 'gnuplot/makefile.tc' -a X"$1" != X"-c"; then
  1146.     echo 'x - skipping gnuplot/makefile.tc (File already exists)'
  1147.     rm -f _shar_wnt_.tmp
  1148. else
  1149. > _shar_wnt_.tmp
  1150. echo 'x - extracting gnuplot/makefile.tc (Text)'
  1151. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/makefile.tc' &&
  1152. # make file for Borland C++ 2.0/Turbo C++ 1.0/Turbo C 2.0
  1153. # uses Borland proprietry overlay manager
  1154. # Modified from the TurboC makefile by Maurice Castro
  1155. # The compile and link includes debug flags.  Take them out if you
  1156. # do not want them included  (-y -v -M, /m /s /v /l)
  1157. X
  1158. # where to place gnuplot.gih helpfile
  1159. HELPFILE = gnuplot.gih
  1160. # location of Turbo C compiler
  1161. # if this is changed then linkopt.tc/linkopt.tco will need to be edited.
  1162. TC = c:\tc
  1163. # name of C compiler
  1164. CC = bcc
  1165. #CC = tcc
  1166. # location of TLINK.EXE and TCC.EXE or BCC.EXE
  1167. BIN = $(TC)\bin\\
  1168. #BIN =
  1169. # location of BGI files,
  1170. # change this line if not in TC directory, i.e. $(TC)\bgi
  1171. BGI = $(TC)\bgi
  1172. # location of bgiobj.exe tool - convertion of BGI to a linkable OBJ file.
  1173. BGIOBJ = $(TC)\bgi\\
  1174. #BGIOBJ =
  1175. X
  1176. # -c means don't link, -f means emulate 8087 if not present
  1177. # -ml means use large model (large code, large data)
  1178. # -M means produce link map
  1179. # -y means include line numbers for debugger
  1180. # -v means include debug info
  1181. # -w- means ignore warnings and do not report them
  1182. # -DREADLINE to use the history/line editing capability. If you want this 
  1183. #    capability add -DREADLINE to CFLAGS then add 'readline' to linkopt.tc
  1184. #    and to linkopt.tco in the /o section.
  1185. CFLAGS = -c -f -ml -M -y -v -w- -I$(TC)\include -DMSDOS -DPC
  1186. TERMFLAGS =
  1187. X
  1188. # With Overlay Support
  1189. #OVLY1 = -Y
  1190. #OVLY2 = -Yo
  1191. # Without Overlay Support
  1192. OVLY1 =
  1193. OVLY2 =
  1194. X
  1195. X
  1196. OBJS =     bitmap.obj command.obj contour.obj eval.obj graphics.obj graph3d.obj \
  1197. X    help.obj internal.obj misc.obj parse.obj plot.obj readline.obj \
  1198. X    scanner.obj setshow.obj standard.obj term.obj util.obj version.obj \
  1199. X    cgaf.obj egavgaf.obj hercf.obj attf.obj
  1200. X
  1201. CSOURCE5 = term\aed.trm term\cgi.trm term\dumb.trm term\dxy.trm \
  1202. X    term\eepic.trm term\epson.trm term\fig.trm term\hp26.trm \
  1203. X    term\hp2648.trm term\hpgl.trm term\hpljii.trm 
  1204. CSOURCE6 = term\impcodes.h term\imagen.trm term\object.h \
  1205. X    term\iris4d.trm term\kyo.trm term\latex.trm term\pc.trm 
  1206. CSOURCE7 = term\post.trm term\qms.trm term\regis.trm term\sun.trm \
  1207. X    term\t410x.trm term\tek.trm term\unixpc.trm term\unixplot.trm \
  1208. X    term\v384.trm term\x11.trm
  1209. CSOURCE8 = contour.c
  1210. X
  1211. all: gnuplot.exe $(HELPFILE)
  1212. X
  1213. # use linkopt.tc/linkopt.tco to avoid command-line overflow
  1214. X
  1215. gnuplot.exe: $(OBJS) 
  1216. # With Overlay Support (select one)
  1217. #    $(BIN)tlink /m /s /v /l @linkopt.tco
  1218. #    $(BIN)tlink @linkopt.tco 
  1219. # Without Overlay Support
  1220. #    $(BIN)tlink /m /s /v /l @linkopt.tc
  1221. X    $(BIN)tlink @linkopt.tc 
  1222. X
  1223. # default rules
  1224. X
  1225. .c.obj:
  1226. X    $(BIN)$(CC) $(OVLY2) $(CFLAGS) $<
  1227. X
  1228. # The default for files is to be compiled for overlaying if OVLY1 and 
  1229. # OVLY2 are defined.  plot.c and parse.c are not suitable for overlaying.
  1230. X
  1231. bitmap.obj: bitmap.c bitmap.h plot.h
  1232. X
  1233. command.obj: command.c plot.h setshow.h help.h
  1234. X    $(BIN)$(CC) $(OVLY2) $(CFLAGS) -DHELPFILE="$(HELPFILE)" command.c
  1235. X
  1236. contour.obj: contour.c plot.h
  1237. X
  1238. eval.obj: eval.c plot.h
  1239. X
  1240. graphics.obj: graphics.c plot.h setshow.h
  1241. X
  1242. graph3d.obj: graphics.c plot.h setshow.h
  1243. X
  1244. help.obj: help.c plot.h help.h
  1245. X
  1246. internal.obj: internal.c plot.h
  1247. X
  1248. misc.obj: misc.c plot.h setshow.h help.h
  1249. X
  1250. parse.obj: parse.c plot.h
  1251. X    $(BIN)$(CC) $(OVLY1) $(CFLAGS) parse.c
  1252. X
  1253. plot.obj: plot.c plot.h setshow.h
  1254. X    $(BIN)$(CC) $(OVLY1) $(CFLAGS) plot.c
  1255. X
  1256. readline.obj: readline.c
  1257. X
  1258. scanner.obj: scanner.c plot.h
  1259. X
  1260. setshow.obj: setshow.c plot.h setshow.h
  1261. X
  1262. standard.obj: standard.c plot.h
  1263. X
  1264. term.obj: term.c term.h plot.h setshow.c bitmap.h $(CSOURCE5) $(CSOURCE6) $(CSOURCE7)
  1265. X    $(BIN)$(CC) $(OVLY2) $(CFLAGS) $(TERMFLAGS) -Iterm term.c
  1266. X
  1267. util.obj: util.c plot.h
  1268. X
  1269. version.obj: version.c
  1270. X
  1271. # convert gnuplot.doc to gnuplot.gih
  1272. $(HELPFILE): doc2gih.exe docs\gnuplot.doc
  1273. X    doc2gih docs\gnuplot.doc $(HELPFILE)
  1274. X
  1275. doc2gih.exe: docs\doc2gih.c
  1276. X    $(BIN)$(CC) -I$(TC)\include -L$(TC)\lib docs\doc2gih.c
  1277. X
  1278. # convert Borland Graphics Interface files to object for linking
  1279. cgaf.obj: $(BGI)\cga.bgi
  1280. X    $(BGIOBJ)bgiobj /F $(BGI)\cga
  1281. X
  1282. egavgaf.obj: $(BGI)\egavga.bgi
  1283. X    $(BGIOBJ)bgiobj /F $(BGI)\egavga
  1284. X
  1285. hercf.obj: $(BGI)\herc.bgi
  1286. X    $(BGIOBJ)bgiobj /F $(BGI)\herc
  1287. X
  1288. attf.obj: $(BGI)\att.bgi
  1289. X    $(BGIOBJ)bgiobj /F $(BGI)\att
  1290. SHAR_EOF
  1291. chmod 0644 gnuplot/makefile.tc ||
  1292. echo 'restore of gnuplot/makefile.tc failed'
  1293. Wc_c="`wc -c < 'gnuplot/makefile.tc'`"
  1294. test 4014 -eq "$Wc_c" ||
  1295.     echo 'gnuplot/makefile.tc: original size 4014, current size' "$Wc_c"
  1296. rm -f _shar_wnt_.tmp
  1297. fi
  1298. # ============= gnuplot/linkopt.vms ==============
  1299. if test -f 'gnuplot/linkopt.vms' -a X"$1" != X"-c"; then
  1300.     echo 'x - skipping gnuplot/linkopt.vms (File already exists)'
  1301.     rm -f _shar_wnt_.tmp
  1302. else
  1303. > _shar_wnt_.tmp
  1304. echo 'x - extracting gnuplot/linkopt.vms (Text)'
  1305. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/linkopt.vms' &&
  1306. sys$library:vaxcrtl/share
  1307. SHAR_EOF
  1308. chmod 0666 gnuplot/linkopt.vms ||
  1309. echo 'restore of gnuplot/linkopt.vms failed'
  1310. Wc_c="`wc -c < 'gnuplot/linkopt.vms'`"
  1311. test 26 -eq "$Wc_c" ||
  1312.     echo 'gnuplot/linkopt.vms: original size 26, current size' "$Wc_c"
  1313. rm -f _shar_wnt_.tmp
  1314. fi
  1315. # ============= gnuplot/term/README ==============
  1316. if test ! -d 'gnuplot/term'; then
  1317.     echo 'x - creating directory gnuplot/term'
  1318.     mkdir 'gnuplot/term'
  1319. fi
  1320. if test -f 'gnuplot/term/README' -a X"$1" != X"-c"; then
  1321.     echo 'x - skipping gnuplot/term/README (File already exists)'
  1322.     rm -f _shar_wnt_.tmp
  1323. else
  1324. > _shar_wnt_.tmp
  1325. echo 'x - extracting gnuplot/term/README (Text)'
  1326. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/term/README' &&
  1327. DOCUMENTATION FOR GNUPLOT TERMINAL DRIVER WRITERS
  1328. By Russell Lang 1/90
  1329. X
  1330. Information on each terminal device driver is contained in term.c and
  1331. the term/*.trm files.  Each driver is contained in a .trm file and is 
  1332. #include'd into term.c.  Each driver has a set of initialisers in 
  1333. term.c for term_tbl[], an array of struct termentry.
  1334. X
  1335. Here is the definition of the struct termentry from plot.h:
  1336. X
  1337. struct termentry {
  1338. X    char *name;
  1339. X    char *description;
  1340. X    unsigned int xmax,ymax,v_char,h_char,v_tic,h_tic;
  1341. X    FUNC_PTR options,init,reset,text,scale,graphics,move,vector,linetype,
  1342. X        put_text,text_angle,justify_text,point,arrow;
  1343. };
  1344. X
  1345. Here's a brief description of each variable:
  1346. X
  1347. The char *name is a pointer to a string containing the name
  1348. of the terminal.  This name is used by the 'set terminal' and 
  1349. 'show terminal' commands.  
  1350. The name must be unique and must not be confused with an abbreviation 
  1351. of another name.  For example if the name "postscript" exists, it is not
  1352. possible to have another name "postscript2".
  1353. Keep the name under 15 characters.
  1354. X
  1355. The char *description is a pointer to a string containing a
  1356. description of the terminal, which is displayed in response
  1357. to the 'set terminal' command.  
  1358. Keep the description under 60 characters.
  1359. X
  1360. xmax is the maximum number of points in the x direction.  
  1361. The range of points used by gnuplot is 0 to xmax-1.
  1362. X
  1363. ymax is the maximum number of points in the y direction.  
  1364. The range of points used by gnuplot is 0 to ymax-1.
  1365. X
  1366. v_char is the height of characters, in the same units as xmax and ymax.
  1367. The border for labelling at the top and bottom of the plot is 
  1368. calculated using v_char.  
  1369. v_char is used as the vertical line spacing for characters.
  1370. X
  1371. h_char is the width of characters, in the same units as xmax and ymax.
  1372. The border for labelling at the left and right of the plot is 
  1373. calculated using h_char.  
  1374. If the _justify_text function returns FALSE, h_char is used to justify 
  1375. text right or centre.  If characters are not fixed width, then the 
  1376. _justify_text function must correctly justify the text.
  1377. X
  1378. v_tic is the vertical size of tics along the x axis, 
  1379. in the same units as ymax.
  1380. X
  1381. h_tic is the horizontal size of tics along the y axis, 
  1382. in the same units as xmax.
  1383. X
  1384. X
  1385. Here's a brief description of what each term.c function does:
  1386. X
  1387. _options()  Called when terminal type is selected.  
  1388. This procedure should parse options on the command line.  A list of the 
  1389. currently selected options should be stored in term_options[] in a form 
  1390. suitable for use with the set term command.  term_options[] is used by 
  1391. the save command.  Use options_null() if no options are available. 
  1392. X
  1393. _init()  Called once, when the device is first selected.  This procedure
  1394. should set up things that only need to be set once, like handshaking and
  1395. character sets etc...
  1396. X
  1397. _reset()  Called when gnuplot is exited, the output device changed or
  1398. the terminal type changed.  This procedure should reset the device, 
  1399. possibly flushing a buffer somewhere or generating a form feed.
  1400. X
  1401. _scale(xs,ys) Called just before _graphics(). This takes the x and y
  1402. scaling factors as information. If the terminal would like to do its
  1403. own scaling, it returns TRUE. Otherwise, it can ignore the information
  1404. and return FALSE: do_plot will do the scaling for you. null_scale is
  1405. provided to do just this, so most drivers can ignore this function
  1406. entirely. The Latex driver is currently the only one providing its own
  1407. scaling.
  1408. X
  1409. _graphics()  Called just before a plot is going to be displayed.  This
  1410. procedure should set the device into graphics mode.  Devices which can't
  1411. be used as terminals (like plotters) will probably be in graphics mode 
  1412. always and therefore won't need this.
  1413. X
  1414. _text()  Called immediately after a plot is displayed.  This procedure 
  1415. should set the device back into text mode if it is also a terminal, so
  1416. that commands can be seen as they're typed.  Again, this will probably
  1417. do nothing if the device can't be used as a terminal.
  1418. X
  1419. _move(x,y)  Called at the start of a line.  The cursor should move to the
  1420. (x,y) position without drawing.
  1421. X
  1422. _vector(x,y)  Called when a line is to be drawn.  This should display a line
  1423. from the last (x,y) position given by _move() or _vector() to this new (x,y)
  1424. position.
  1425. X
  1426. _linetype(lt)  Called to set the line type before text is displayed or
  1427. line(s) plotted.  This procedure should select a pen color or line
  1428. style if the device has these capabilities.  
  1429. lt is an integer from -2 to 0 or greater.  
  1430. An lt of -2 is used for the border of the plot.
  1431. An lt of -1 is used for the X and Y axes.  
  1432. lt 0 and upwards are used for plots 0 and upwards.
  1433. If _linetype() is called with lt greater than the available line types, 
  1434. it should map it to one of the available line types.
  1435. Most drivers provide 9 different linetypes (lt is 0 to 8).
  1436. X
  1437. _put_text(x,y,str)  Called to display text at the (x,y) position, 
  1438. while in graphics mode.   The text should be vertically (with respect 
  1439. to the text) justified about (x,y).  The text is rotated according 
  1440. to _text_angle and then horizontally (with respect to the text)
  1441. justified according to _justify_text.
  1442. X
  1443. _text_angle(ang)  Called to rotate the text angle when placing the y label.
  1444. If ang = 0 then text is horizontal.  If ang = 1 then text is vertically
  1445. upwards.  Returns TRUE if text can be rotated, FALSE otherwise.
  1446. X
  1447. _justify_text(mode)  Called to justify text left, right or centre.
  1448. If mode = LEFT then text placed by _put_text is flushed left against (x,y).
  1449. If mode = CENTRE then centre of text is at (x,y).  
  1450. If mode = RIGHT then text is placed flushed right against (x,y).
  1451. Returns TRUE if text can be justified
  1452. Returns FALSE otherwise and then _put_text assumes text is flushed left;
  1453. justification of text is then performed by calculating the text width
  1454. using strlen(text) * h_char.
  1455. X
  1456. _point(x,y,point)  Called to place a point at position (x,y).
  1457. point is -1 or an integer from 0 upwards.  
  1458. 6 point types (numbered 0 to 5) are normally provided.  
  1459. Point type -1 is a dot.
  1460. If point is more than the available point types then it should 
  1461. be mapped back to one of the available points.
  1462. Two _point() functions called do_point() and line_and_point() are 
  1463. provided in term.c and should be suitable for most drivers.  
  1464. do_point() draws the points in the current line type.
  1465. If your driver uses dotted line types (generally because it is
  1466. monochrome), you should use line_and_point() which changes to 
  1467. line type 0 before drawing the point.  line type 0 should be solid.
  1468. X
  1469. _arrow(sx,sy,ex,ey,head)  Called to draw an arrrow from (sx,sy) to (ex,ey).
  1470. A head is drawn on the arrow if head = TRUE.
  1471. An _arrow() function called do_arrow() is provided in term.c which will
  1472. draw arrows using the _move() and _vector() functions.  
  1473. Drivers should use do_arrow unless it causes problems.
  1474. X
  1475. The following should illustrate the order in which calls to these
  1476. routines are made:
  1477. X
  1478. X  _init()
  1479. X    _scale(xs,ys)
  1480. X    _graphics()
  1481. X      _linetype(lt)
  1482. X      _move(x,y)
  1483. X      _vector(x,y)
  1484. X      _point(x,y,point)
  1485. X      _text_angle(angle)
  1486. X      _justify(mode)
  1487. X      _put_text(x,y,text)
  1488. X      _arrow(sx,sy,ex,ey)
  1489. X    _text()
  1490. X    _graphics()
  1491. X      .
  1492. X      .
  1493. X    _text()
  1494. X  _reset()
  1495. X
  1496. X
  1497. SHAR_EOF
  1498. chmod 0644 gnuplot/term/README ||
  1499. echo 'restore of gnuplot/term/README failed'
  1500. Wc_c="`wc -c < 'gnuplot/term/README'`"
  1501. test 7115 -eq "$Wc_c" ||
  1502.     echo 'gnuplot/term/README: original size 7115, current size' "$Wc_c"
  1503. rm -f _shar_wnt_.tmp
  1504. fi
  1505. # ============= gnuplot/term/aed.trm ==============
  1506. if test -f 'gnuplot/term/aed.trm' -a X"$1" != X"-c"; then
  1507.     echo 'x - skipping gnuplot/term/aed.trm (File already exists)'
  1508.     rm -f _shar_wnt_.tmp
  1509. else
  1510. > _shar_wnt_.tmp
  1511. echo 'x - extracting gnuplot/term/aed.trm (Text)'
  1512. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/term/aed.trm' &&
  1513. /* GNUPLOT - aed.trm */
  1514. /*
  1515. X * Copyright (C) 1990
  1516. X *
  1517. X * Permission to use, copy, and distribute this software and its
  1518. X * documentation for any purpose with or without fee is hereby granted, 
  1519. X * provided that the above copyright notice appear in all copies and 
  1520. X * that both that copyright notice and this permission notice appear 
  1521. X * in supporting documentation.
  1522. X *
  1523. X * Permission to modify the software is granted, but not the right to
  1524. X * distribute the modified code.  Modifications are to be distributed 
  1525. X * as patches to released version.
  1526. X *  
  1527. X * This software  is provided "as is" without express or implied warranty.
  1528. X * 
  1529. X * This file is included by ../term.c.
  1530. X *
  1531. X * This terminal driver supports:
  1532. X *   AED terminals
  1533. X *
  1534. X * AUTHORS
  1535. X *     Colin Kelley, Thomas Williams, Russell Lang
  1536. X *
  1537. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  1538. X * 
  1539. X */
  1540. X
  1541. #define AED_XMAX 768
  1542. #define AED_YMAX 575
  1543. X
  1544. #define AED_XLAST (AED_XMAX - 1)
  1545. #define AED_YLAST (AED_YMAX - 1)
  1546. X
  1547. #define AED_VCHAR    13
  1548. #define AED_HCHAR    8
  1549. #define AED_VTIC    8
  1550. #define AED_HTIC    7
  1551. X
  1552. /* slightly different for AED 512 */
  1553. #define AED5_XMAX 512
  1554. #define AED5_XLAST (AED5_XMAX - 1)
  1555. X
  1556. AED_init()
  1557. {
  1558. X    fprintf(outfile,
  1559. X    "\033SEN3DDDN.SEC.7.SCT.0.1.80.80.90.SBC.0.AAV2.MOV.0.9.CHR.0.FFD");
  1560. /*   2            3     4                5     7    6       1
  1561. X    1. Clear Screen
  1562. X    2. Set Encoding
  1563. X    3. Set Default Color
  1564. X    4. Set Backround Color Table Entry
  1565. X    5. Set Backround Color
  1566. X    6. Move to Bottom Lefthand Corner
  1567. X    7. Anti-Alias Vectors
  1568. */
  1569. }
  1570. X
  1571. X
  1572. AED_graphics()
  1573. {
  1574. X    fprintf(outfile,"\033FFD\033");
  1575. }
  1576. X
  1577. X
  1578. AED_text()
  1579. {
  1580. X    fprintf(outfile,"\033MOV.0.9.SEC.7.XXX");
  1581. }
  1582. X
  1583. X
  1584. X
  1585. AED_linetype(linetype)
  1586. int linetype;
  1587. {
  1588. static int color[2+9] = { 7, 1, 6, 2, 3, 5, 1, 6, 2, 3, 5 };
  1589. static int type[2+9] = { 85, 85, 255, 255, 255, 255, 255, 85, 85, 85, 85 };
  1590. X
  1591. X    if (linetype >= 10)
  1592. X        linetype %= 10;
  1593. X    fprintf(outfile,"\033SLS%d.255.",type[linetype+2]);
  1594. X    fprintf(outfile,"\033SEC%d.",color[linetype+2]);
  1595. }
  1596. X
  1597. X
  1598. X
  1599. AED_move(x,y)
  1600. int x,y;
  1601. {
  1602. X    fprintf(outfile,"\033MOV%d.%d.",x,y);
  1603. }
  1604. X
  1605. X
  1606. AED_vector(x,y)
  1607. int x,y;
  1608. {
  1609. X    fprintf(outfile,"\033DVA%d.%d.",x,y);
  1610. }
  1611. X
  1612. X
  1613. AED_put_text(x,y,str)
  1614. int x,y;
  1615. char str[];
  1616. {
  1617. X    AED_move(x,y - AED_VCHAR/2 + 2);
  1618. X    fprintf(outfile,"\033XXX%s\033",str);
  1619. }
  1620. X
  1621. X
  1622. #define hxt (AED_HTIC/2)
  1623. #define hyt (AED_VTIC/2)
  1624. X
  1625. AED_reset()
  1626. {
  1627. X    fprintf(outfile,"\033SCT0.1.0.0.0.SBC.0.FFD");
  1628. }
  1629. X
  1630. SHAR_EOF
  1631. chmod 0666 gnuplot/term/aed.trm ||
  1632. echo 'restore of gnuplot/term/aed.trm failed'
  1633. Wc_c="`wc -c < 'gnuplot/term/aed.trm'`"
  1634. test 2311 -eq "$Wc_c" ||
  1635.     echo 'gnuplot/term/aed.trm: original size 2311, current size' "$Wc_c"
  1636. rm -f _shar_wnt_.tmp
  1637. fi
  1638. # ============= gnuplot/term/bigfig.trm ==============
  1639. if test -f 'gnuplot/term/bigfig.trm' -a X"$1" != X"-c"; then
  1640.     echo 'x - skipping gnuplot/term/bigfig.trm (File already exists)'
  1641.     rm -f _shar_wnt_.tmp
  1642. else
  1643. > _shar_wnt_.tmp
  1644. echo 'x - extracting gnuplot/term/bigfig.trm (Text)'
  1645. sed 's/^X//' << 'SHAR_EOF' > 'gnuplot/term/bigfig.trm' &&
  1646. /* GNUPLOT - fig.trm */
  1647. /*
  1648. X * Copyright (C) 1990
  1649. X *
  1650. X * Permission to use, copy, and distribute this software and its
  1651. X * documentation for any purpose with or without fee is hereby granted,
  1652. X * provided that the above copyright notice appear in all copies and
  1653. X * that both that copyright notice and this permission notice appear
  1654. X * in supporting documentation.
  1655. X *
  1656. X * Permission to modify the software is granted, but not the right to
  1657. X * distribute the modified code.  Modifications are to be distributed
  1658. X * as patches to released version.
  1659. X *
  1660. X * This software  is provided "as is" without express or implied warranty.
  1661. X *
  1662. X * This file is included by ../term.c.
  1663. X *
  1664. X * This terminal driver supports:
  1665. X *  Fig graphics language
  1666. X *
  1667. X * AUTHORS
  1668. X *  Micah Beck, David Kotz
  1669. X *
  1670. X * send your comments or suggestions to (pixar!info-gnuplot@sun.com).
  1671. X *
  1672. X */
  1673. /*
  1674. X * Original for Fig code output by Micah Beck, 1989
  1675. X * Department of Computer Science, Cornell University
  1676. X * Updated by David Kotz for gnuplot 2.0
  1677. X * More efficient output by Ian Dall
  1678. X * Increased size of plot by Ian Dall
  1679. X */
  1680. #define BFIG_HTIC       (7*FIG_RES/80)
  1681. #define BFIG_VTIC       (7*FIG_RES/80)
  1682. #define BFIG_HCHAR      (9*FIG_RES/80)
  1683. #define BFIG_FONT_S     (16)
  1684. #define BFIG_VCHAR      ((BFIG_FONT_S)*FIG_RES/80)  /* height in pixels of font
  1685. X        */
  1686. #define BFIG_ARROW_WIDTH BFIG_HTIC
  1687. #define BFIG_ARROW_HEIGHT BFIG_HTIC
  1688. /* 7 inches wide by 5 inches high */
  1689. #define BFIG_XMAX (8 * FIG_RES)
  1690. #define BFIG_YMAX (5 * FIG_RES)
  1691. #define BFIG_XOFF (FIG_RES/2)
  1692. #define BFIG_YOFF (FIG_RES/2)
  1693. BFIG_vector(ux,uy)
  1694. X     unsigned int ux,uy;
  1695. {
  1696. X  int x=ux, y=uy;
  1697. X  if (FIG_polyvec_stat != FIG_poly_part)
  1698. X    {
  1699. X      fprintf(outfile, "%d %d %d %d %d %d %d %d %6.3f  %d %d\n",
  1700. X              O_POLYLINE, T_POLYLINE,
  1701. X              FIG_type, 1, FIG_DEFAULT, FIG_DEFAULT, FIG_DEFAULT, FIG_DEFAULT, FIG_spacing,
  1702. X              0, 0);
  1703. X      fprintf(outfile, "%d %d",
  1704. X              BFIG_XOFF + FIG_posx, BFIG_YMAX + BFIG_YOFF - FIG_posy);
  1705. X      FIG_poly_vec_cnt = 1;
  1706. X      FIG_polyvec_stat = FIG_poly_part;
  1707. X    }
  1708. X  fprintf(outfile, " %d %d",
  1709. X          BFIG_XOFF +  x, BFIG_YMAX + BFIG_YOFF-y);
  1710. SHAR_EOF
  1711. true || echo 'restore of gnuplot/term/bigfig.trm failed'
  1712. fi
  1713. echo 'End of  part 14'
  1714. echo 'File gnuplot/term/bigfig.trm is continued in part 15'
  1715. echo 15 > _shar_seq_.tmp
  1716. exit 0
  1717.  
  1718. exit 0 # Just in case...
  1719. -- 
  1720. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1721. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1722. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1723. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1724.