home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume21 / ipl / part06 < prev    next >
Text File  |  1990-03-22  |  31KB  |  1,057 lines

  1. Subject:  v21i037:  2D graphic system with table beautifier, Part06/14
  2. Newsgroups: comp.sources.unix
  3. Approved: rsalz@uunet.UU.NET
  4. X-Checksum-Snefru: 49b657e8 e2cfc57f c7bf88f8 7bb9b4b7
  5.  
  6. Submitted-by: Steve Grubb <uunet!lsr-vax!scg>
  7. Posting-number: Volume 21, Issue 37
  8. Archive-name: ipl/part06
  9.  
  10. # ipl part06
  11. #    This is a shell archive.
  12. #    Remove everything above and including the cut line.
  13. #    Then run the rest of the file through sh.
  14. #---------------------- cut here -----------------------------
  15. #!/bin/sh
  16. # shar:    Shell Archiver
  17. #    Run the following text with /bin/sh to create:
  18. #        src/dataclick.c
  19. #        src/distribution.c
  20. #        src/draw.c
  21. #        src/errorbars.c
  22. #        src/exit.c
  23. #        src/gdp.d
  24. #        src/gdp.h
  25. #        src/gdp.x
  26. #        src/get_point.c
  27. #        src/getdata.c
  28. #        src/gget.c
  29. #        src/graphic.c
  30. #        src/graphic.d
  31. #        src/graphic.h
  32. #        src/graphic.x
  33. cat << SHAR_EOF > src/dataclick.c
  34. /* This allows coordinate data to be entered using the mouse. */
  35.  
  36. #include "ipl.x"
  37.  
  38. dataclick( fnm )
  39. char fnm[];
  40. {
  41.  
  42. double x, y;
  43. int s;
  44. FILE *fp;
  45.  
  46. if( strlen( fnm ) > 0 ) {
  47.     fp = fopen( fnm, "w" );
  48.     if( fp == NULL ) { fprintf( stderr, "Can't open file.\n" ); return( 0 ); }
  49.     }
  50.  
  51. message( "", "Point and click with", "left mouse button.", "Press right button to quit." );
  52. while( 1 ) {
  53.     get_event( &x, &y, &s );
  54.     if( s == MOUSE_RIGHT ) break;
  55.     if( s == MOUSE_LEFT ) { 
  56.         sprintf( Buf, "%-9.3f %-9.3f ", ab_x( x ), ab_y( y ) ); 
  57.         message( Buf, "", "(Data coordinates)", "Press right button to quit." );
  58.         if( strlen( fnm ) > 0 ) fprintf( fp, "%s\n", Buf );
  59.         point( x, y, "sym6a", 0.08 );
  60.         get_event( &x, &y, &s ); /* get spurious bounce-back (???) */
  61.         }
  62.  
  63.     }
  64. if( strlen( fnm ) > 0 ) fclose( fp );
  65. }
  66. SHAR_EOF
  67. ############################
  68.  
  69. cat << SHAR_EOF > src/distribution.c
  70. /* distribution() - produces scatter plots.  If cluster is passed
  71.     as YES, duplicate values will cluster around the point.
  72.     Data must be sorted numerically for this to work.  If
  73.     cluster == NO, duplicate points will overstrike.
  74. */
  75. #include "ipl.x"
  76.  
  77. Distribution( )
  78. {
  79. int     i, j, 
  80.     dups, 
  81.     cluster, 
  82.     p, 
  83.     dist, 
  84.     justdist,
  85.     xfield, 
  86.     yfield, 
  87.     idfield,
  88.     sizefield,
  89.     shadefield,
  90.     markfield;
  91. double     adjx, adjy, 
  92.     xdat, ydat,
  93.     x, y, 
  94.     prevx, prevy, 
  95.     charh, charv, 
  96.     size,
  97.     sizescale,
  98.     shade,
  99.     shadescale,
  100.     distlen;
  101. char     c[20];
  102. FILE     *fp, 
  103.     *fp2;
  104. static double xofst[38] = { 0, 0, 4, 0, -4, 4, -4, -4, 4,
  105.     0, -8, 0, 8, 4, -8, 4, 8, -4, -8, -4, 8,
  106.     0, 0, 12, -12, 4, 4, 12, -12, -4, -4, 12, -12,
  107.     8, -8, -8, 8 };
  108. static double yofst[38] = { 0, 4, 0, -4, 0, 4, -4, 4, -4,
  109.     -8, 0, 8, 0, -8, 4, 8, 4, -8, -4, 8, -4,
  110.     12, -12, 0, 0, 12, -12, 4, 4, 12, -12, -4, -4,
  111.     8, -8, 8, -8 };
  112. static double distofst[38] = { 0, 1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 
  113.     9, -9, 10, -10, 11, -11, 12, -12, 13, -13, 14, -14, 15, -15, 16, -16, 17, -17, 18, -18 };
  114.  
  115. gget( Buf, "Xfield" ); xfield = atoi( Buf );
  116. gget( Buf, "Yfield" ); yfield = atoi( Buf );
  117. if( xfield < 1 ) { fprintf( stderr, "1 or 2 fdata fields need to be given for distributions.\n" ); gdp_exit(); }
  118. if( yfield < 1 ) {
  119.     justdist = YES; 
  120.     yfield = xfield;
  121.     }
  122. else justdist = NO;
  123. gget( Buf, "Idfield" ); idfield = atoi( Buf );
  124. gget( Buf, "Mark.field" ); markfield = atoi( Buf );
  125.  
  126. gget( c, "Mark" );
  127. gget( Buf, "Mark.font" ); NTfont( Buf ); 
  128. gget( Buf, "Mark.size" ); NTptsize( atof( Buf ) );
  129. charv = Chh / 2.0;
  130. charh = Chh / 4.0;
  131. size = Chh * 0.4;
  132. gget( Buf, "Cluster" ); if( Buf[0] == 'y' ) cluster = YES; else cluster = NO;
  133. dist = NO;
  134. gget( Buf, "Axdist" ); 
  135. if( Buf[0] == 'y' ) { 
  136.     dist = YES; 
  137.     gget( Buf, "Axdist.length" ); distlen = atof( Buf );
  138.     }
  139. gget( Buf, "Sizefield" ); sizefield = atoi( Buf );
  140. gget( Buf, "Sizescale" ); sizescale = atof( Buf );
  141. gget( Buf, "Shadefield" ); shadefield = atoi( Buf );
  142. gget( Buf, "Shadescale" ); shadescale = atof( Buf );
  143.  
  144. if( cluster ) {        /* sort the data numerically */
  145.     /* write out data */
  146.     fp = fopen( Tempfile, "w" );
  147.     if( fp == NULL ) fprintf( stderr, "Distribution can't open: %s", Tempfile );    
  148.     for( i = 0; i < N_d_rows; i++ ) {
  149.         for( j = 0; j < N_d_fields; j++ ) fprintf( fp, "%s ", D[i][j] );
  150.         fprintf( fp, "\n" );
  151.         }
  152.     fclose( fp );
  153.     /* build Unix sort command */
  154.     sprintf( Buf, "sort -n %s +%d -%d +%d -%d -o %s", Tempfile, xfield-1, xfield, yfield-1, yfield, Tempfile );
  155.     system( Buf );
  156.     fp2 = fopen( Tempfile, "r" );
  157.     for( i = 0; i < N_d_rows; i++ ) {
  158.         for( j = 0; j < N_d_fields; j++ ) { fscanf( fp2, "%s", D[i][j] ); }
  159.         }
  160.     fclose( fp2 );
  161.     }
  162.  
  163. x = -99999.0;
  164. y = -99999.0;
  165. dups = 0;
  166. for( i = 0; i < N_d_rows; i++ ) {
  167.     if( (!goodnum( D[i][yfield-1], &p ) && !justdist) || !goodnum( D[i][xfield-1], &p )) {
  168.         if( idfield ) fprintf( stderr, "%s ", D[i][idfield-1] );
  169.         else fprintf( stderr, "row %d ", i ); 
  170.          fprintf( stderr, "is bad: (%s,%s) (Warning)\n", D[i][xfield-1], D[i][yfield-1] );
  171.         continue;
  172.         }
  173.     x = da_x( atof( D[i][xfield-1] ) );
  174.     y = da_y( atof( D[i][yfield-1] ) );
  175.     if( (!justdist && (y < Ylo || y > Yhi )) || x < Xlo || x > Xhi ) { 
  176.         if( idfield )fprintf( stderr, "%s ", D[i][idfield-1] );
  177.         else fprintf( stderr, "Row %d ", i );
  178.         fprintf( stderr, "is out of bounds: (%s,%s) (Warning)\n", D[i][xfield-1], D[i][yfield-1] );
  179.         continue; 
  180.         }  
  181.     if( cluster && (x == prevx && y == prevy ) ) {
  182.         dups++;
  183.         if( dups > 36 ) dups = 1;
  184.         if( justdist ) adjx = x + (.01*distofst[dups]);
  185.         else adjx = x + (.01*xofst[dups]);
  186.         adjy = y + (.01*yofst[dups]);
  187.         }
  188.     else    {
  189.         dups = 0;
  190.         prevx = x;
  191.         prevy = y;
  192.         adjx = x;
  193.         adjy = y;
  194.         }
  195.     if( !justdist ) {
  196.         if( sizefield > 0 && sizefield <= 24 ) {
  197.             size = ( atof( D[i][sizefield-1] ) * sizescale) / 144.0; 
  198.             if( size < 0.001 || size > 3 ) {
  199.                 fprintf( stderr, "warning, rec. %d, abnormal size data value\n", i  ); 
  200.                 }
  201.             }
  202.         if( shadefield > 0 && shadefield <= 24 ) {
  203.             shade = atof( D[i][shadefield-1] ) * shadescale;
  204.             if( shade < 0 || shade > 1 ) {
  205.                 fprintf( stderr, "warning, rec %d, abnormal shade data value, truncated.\n", i );
  206.                 if( shade < 0 ) shade = 0;
  207.                 if( shade > 1 ) shade = 1;
  208.                 }
  209.             sprintf( c, "%s%4.2f", c, shade );
  210.             }
  211.             
  212.             
  213.         if( strncmp( c, "sym", 3 )==0 ) {
  214.             point( adjx, adjy, c, size );
  215.             c[5] = '\0'; /* get rid of shade if any */
  216.             }
  217.         if( markfield || strncmp( c, "sym", 3 )!=0 ) {
  218.             NTmov( (adjx-(charh*0.20))-1, adjy-(charv*0.48) );
  219.             if( markfield ) NTcentext( D[i][markfield-1], 2 );
  220.             else NTcentext( c, 2 );
  221.             }
  222.         }
  223.     else if( justdist ) {
  224.         NTmov( adjx, Ylo ); NTlin( adjx, Yhi );
  225.         }
  226.     if( dist && !justdist ) {
  227.         NTmov( Xhi, adjy ); NTlin( Xhi+distlen, adjy );
  228.         NTmov( adjx, Yhi ); NTlin( adjx, Yhi+distlen );
  229.         }
  230.     }
  231. }
  232. SHAR_EOF
  233. ############################
  234.  
  235. cat << SHAR_EOF > src/draw.c
  236. /* draw - for drawing with lines */
  237. #include "ipl.x"
  238. #define ABSOLUTE 0
  239. #define DATA 1
  240.  
  241. Draw( )
  242. {
  243. int sys, n, i, p;
  244. double mag, thick, x, y, x2, y2;
  245. char ltype[10];
  246.  
  247. gget( Buf, "System" );
  248. if( strcmp( Buf, "absolute" )==0 ) sys = ABSOLUTE;
  249. else     {
  250.     sys = DATA;
  251.     if( DXlo == 0 && DXhi == 0 ) { fprintf( stderr, "No graphics area.\n" ); gdp_exit(); }
  252.     }
  253.  
  254. /* get line style parameters */
  255. gget( Buf, "Linetype" ); strcpy( ltype, Buf );
  256.  
  257. gget( Buf, "Linetype.magnify" ); 
  258. if( goodnum( Buf, &p )) mag = atof( Buf );
  259. else mag = 1;
  260.  
  261. gget( Buf, "Linethick" ); thick = atof( Buf );
  262.  
  263.  
  264. /* set line style */
  265. NTlinetype( ltype, thick, mag );
  266.  
  267. /* get points */
  268. gget( Buf, "Points" );
  269. getln( "" );
  270. for( i = 0; i < countln( Buf ); i++ ) {
  271.     n = sscanf( getln( Buf ), "%lf %lf %lf %lf", &x, &y, &x2, &y2 );
  272.     if( sys == DATA && n == 2 ) NTl( x, y );
  273.     else if( sys == DATA && n == 2 && i == 0 ) NTm( x, y );
  274.     else if( sys == DATA && n == 4 ) { NTm( x, y ); NTl( x2, y2 ); }
  275.     else if( sys == ABSOLUTE && n == 2 ) NTlin( x, y );
  276.     else if( sys == ABSOLUTE && n == 2 && i == 0 ) NTmov( x, y );
  277.     else if( sys == ABSOLUTE && n == 4 ) { NTmov( x, y ); NTlin( x2, y2 ); }
  278.     else { fprintf( stderr, "Points should contain either one or two coord pairs per line.\n" ); gdp_exit(); }
  279.     }
  280.  
  281. NTnormline(); /* return line to normal */
  282. }    
  283. SHAR_EOF
  284. ############################
  285.  
  286. cat << SHAR_EOF > src/errorbars.c
  287. #include "ipl.x"
  288.  
  289. Errorbars( )
  290. {
  291. int i, xfld, yfld, efld, dubl;
  292. double x, y, err, tlen, ofs;
  293.  
  294. gget( Buf, "Xfield" );
  295. xfld = atoi( Buf );
  296. if( xfld < 1 || xfld > 24 ) { fprintf( stderr, "Xfield bad.\n" ); gdp_exit(); }
  297.  
  298. gget( Buf, "Yfield" );
  299. yfld = atoi( Buf );
  300. if( yfld < 1 || yfld > 24 ) { fprintf( stderr, "Yfield bad.\n" ); gdp_exit(); }
  301.  
  302. gget( Buf, "Errfield" );
  303. efld = atoi( Buf );
  304. if( efld < 1 || efld > 24 ) { fprintf( stderr, "Errfield bad.\n" ); gdp_exit(); }
  305.  
  306. gget( Buf, "Offset" );
  307. ofs = atof( Buf );
  308.  
  309. gget( Buf, "Double" );
  310. if( Buf[0] == 'y' ) dubl = 1;
  311. else dubl = 0;
  312.  
  313. gget( Buf, "Linethick" );
  314. if( strlen( Buf ) > 0 ) NTlinetype( "0", atof( Buf ), 1.0 );
  315.  
  316. gget( Buf, "Taillen" );
  317. if( strlen( Buf ) > 0 ) tlen = atof( Buf );
  318.  
  319. for( i = 1; i <= N_d_rows; i++ ) {
  320.     x = atof( D[i-1][xfld-1] ) ;
  321.     y = atof( D[i-1][yfld-1] );
  322.     err = atof( D[i-1][efld-1] );
  323.     if( dubl ) err *= 2.0;
  324.  
  325.     NTmov( da_x(x)+ofs, da_y(y) ); /* top bar */
  326.     NTlin( da_x(x)+ofs, da_y(y+err) );
  327.     NTmov( (da_x(x)-(tlen/2))+ofs, da_y(y+err) ); /* tail */
  328.     NTlin( da_x(x)+(tlen/2)+ofs, da_y(y+err) );
  329.     
  330.     NTmov( da_x(x)+ofs, da_y(y) ); /* bottom bar */
  331.     NTlin( da_x(x)+ofs, da_y(y-err) );
  332.     NTmov( (da_x(x)-(tlen/2))+ofs, da_y(y-err) ); /* tail */
  333.     NTlin( da_x(x)+(tlen/2)+ofs, da_y(y-err) );
  334.     
  335.     }
  336.  
  337. NTnormline();
  338. }
  339. SHAR_EOF
  340. ############################
  341.  
  342. cat << SHAR_EOF > src/exit.c
  343. #include "ipl.x"
  344. Exit( )
  345. {
  346. if( !Hold )NTshow();
  347. unlink( Tempfile );
  348. }
  349. SHAR_EOF
  350. ############################
  351.  
  352. cat << SHAR_EOF > src/gdp.d
  353. #include <stdio.h>
  354. #include "../install.h"
  355. #define TEMPDIR        INSTALL_TMP
  356. #define INLENGTH 120
  357. #define INWIDTH 120
  358. #define MAXARGS 24
  359. #define ARGLEN 100
  360. SHAR_EOF
  361. ############################
  362.  
  363. cat << SHAR_EOF > src/gdp.h
  364.  
  365. #include "gdp.d"
  366. char Chunk[INLENGTH][INWIDTH]; 
  367. char Ichunk[INLENGTH][INWIDTH];
  368. int Ilines, Clines;
  369. char Arg[MAXARGS][ARGLEN+1];
  370. int Argc;
  371. int Do_cons_check;
  372. FILE *Sfp;
  373. char Last_constraint[80];
  374. SHAR_EOF
  375. ############################
  376.  
  377. cat << SHAR_EOF > src/gdp.x
  378. #include "gdp.d"
  379. extern char Chunk[INLENGTH][INWIDTH];
  380. extern char Ichunk[INLENGTH][INWIDTH];
  381. extern int Ilines, Clines;
  382. extern char Arg[MAXARGS][ARGLEN+1];
  383. extern int Argc;
  384. extern int Do_cons_check;
  385. extern FILE *Sfp;
  386. extern char Last_constraint[];
  387. SHAR_EOF
  388. ############################
  389.  
  390. cat << SHAR_EOF > src/get_point.c
  391. /* This allows coordinate data to be entered using the mouse. */
  392.  
  393. #include "ipl.x"
  394.  
  395. get_point( x, y )
  396. double *x, *y;
  397. {
  398.  
  399. int s;
  400. double x2, y2;
  401. char ans[20];
  402.  
  403. if( Dev == 'm' ) { /* terminal interface */
  404.     fprintf( stderr, "Enter a position in inches.  First x: " );
  405.     fgets( ans, 20, stdin ); *x = atof( ans );
  406.     fprintf( stderr, "Now y: " ); fgets( ans, 20, stdin ); *y = atof( ans );
  407.     return( 1 );
  408.     }
  409.  
  410. get_event( x, y, &s );
  411. point( *x, *y, "sym6a", 0.08 );
  412. get_event( &x2, &y2, &s ); /* get spurious bounce-back (???) */
  413.  
  414. }
  415. SHAR_EOF
  416. ############################
  417.  
  418. cat << SHAR_EOF > src/getdata.c
  419. /* getdata() - Reads plot data.  
  420. */
  421. #include "ipl.x"
  422.  
  423. Getdata( )
  424. {
  425. int i, j, n, startline, stopline, selectall, join, sf, ff, ix, append;
  426. char    datafile[PATHNAME_LEN], selectfields[120], fillfields[120], sfstr[10], tok[80];
  427. FILE    *datafp;
  428.  
  429. gget( Buf, "Startline" );
  430. startline = atoi( Buf );
  431. if( startline == 0 ) startline = 1;
  432. gget( Buf, "Stopline" );
  433. stopline = atoi( Buf );
  434. if( stopline == 0 ) stopline = 9999;
  435.  
  436. gget( selectfields, "Selectfields" ); 
  437. if( strcmp( selectfields, "all" )==0 ) selectall = 1;
  438. else selectall = 0;
  439.  
  440. gget( Buf, "Join" ); 
  441. if( Buf[0] == 'y' ) join = 1;
  442. else join = 0;
  443.  
  444. gget( Buf, "Append" );
  445. if( Buf[0] == 'y' ) append = 1;
  446. else append = 0;
  447.  
  448. datafile[0] = '\0';
  449. gget( Buf, "Datafile" ); 
  450. if( strlen( Buf ) > 0 ) strcpy( datafile, Buf ); 
  451.  
  452. gget( Buf, "Data" );
  453.  
  454. if( Buf[0] != '\0' ) { /* data given in spec file-- put it in a tmp file and read it as usual */
  455.     text_tofile( Buf, Tempfile );
  456.     strcpy( datafile, Tempfile );
  457.     }
  458.  
  459. else if( strlen( datafile ) < 1 ) { fprintf( stderr, "Getdata: no Data or Datafile specified.\n" ); gdp_exit(); }
  460.  
  461. /* open datafile */
  462. if( strcmp( datafile, "-" )==0 ) { 
  463.     datafp = stdin;
  464.     fprintf( stderr, "Note: expecting data on stdin.\n" );
  465.     }
  466. else datafp = fopen( datafile, "r" );
  467. if( datafp == NULL ) datafp = popen( datafile, "r" );
  468. if( datafp == NULL ) { fprintf( stderr, "Cant open data source '%s'\n", datafile ); gdp_exit(); }
  469.         
  470. if( append ) i = N_d_rows;
  471. else i = 0; 
  472.  
  473. j = 1;
  474. while( fgets( Buf, 512, datafp ) != NULL ) {
  475.     if( j < startline ) { j++; continue; }
  476.     if( j > stopline ) break;
  477.     if( sscanf( Buf, "%s", tok ) < 1 ) continue;
  478.     ix = 0; sf = 0; 
  479.     if( join ) ff = N_d_fields;
  480.     else ff = 0;
  481.     while( 1 ) {
  482.         if( ff >= MAX_D_COLS ) {
  483.             fprintf( stderr, "Warning, max of %d fields, extra fields ignored in row %d.\n", MAX_D_COLS, i );
  484.             break;
  485.             }
  486.         strcpy( tok, getok( Buf, &ix ) );
  487.         if( strlen( tok ) < 1 ) break;
  488.         if( selectall ) { 
  489.             sf++;
  490.             if( strlen( tok ) > DATAITEM_LEN-1 ) { 
  491.                 fprintf( stderr, "Item too long (max= %d chars) in row %d fld %d.\n", 
  492.                     DATAITEM_LEN-1, i, sf );
  493.                 gdp_exit();
  494.                 }
  495.             else strcpy( D[i][ff++], tok );
  496.             }
  497.         else     {
  498.             sf++;
  499.             sprintf( sfstr, "%d", sf );
  500.             if( smember( sfstr, selectfields ) ) {
  501.                 if( strlen( tok ) > DATAITEM_LEN-1 ) { 
  502.                     fprintf( stderr, "Item longer than %d chars (row %d fld %d).\n", 
  503.                         DATAITEM_LEN-1, i, sf );
  504.                     gdp_exit();
  505.                     }
  506.                 else strcpy( D[i][ff++], tok );
  507.                 }
  508.             }
  509.         }
  510.     if( datafp == stdin && ff < 1 ) break;
  511.     i++; j++;
  512.     if( i >= MAX_D_ROWS ) { fprintf( stderr, "Warning: using 1st %d rows of data only.\n", MAX_D_ROWS ); break; }
  513.     }
  514.  
  515. if( i < 1 ) { fprintf( stderr, "Plot data source (%s) is empty", datafile ); gdp_exit(); }
  516. if( datafp == stdin ) fclose( datafp );
  517. N_d_fields = ff;
  518. if( join && i != N_d_rows ) { 
  519.     fprintf( stderr, "Not enough records to join, expecting %d.\n", N_d_rows ); 
  520.     gdp_exit();
  521.     }
  522. else N_d_rows = i;
  523.  
  524.  
  525. /* Percents option: for the fields given, change to percents based on the field total */
  526. gget( Buf, "Percents" );
  527. if( strlen( Buf ) > 0 ) {
  528.     double accum;
  529.     int f, pf[24];
  530.     n = sscanf( Buf, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
  531.       &pf[0],&pf[1],&pf[2],&pf[3],&pf[4],&pf[5],&pf[6],&pf[7],&pf[8],&pf[9],&pf[10],&pf[11],&pf[12],&pf[13],&pf[14],
  532.       &pf[15],&pf[16],&pf[17],&pf[18],&pf[19],&pf[20],&pf[21],&pf[22],&pf[23] );
  533.     for( i = 0; i < n; i++ ) {   /* fields */
  534.         accum = 0;
  535.         f = pf[i] -1;
  536.         for( j = 0; j < N_d_rows; j++ )  /* compute row total */
  537.             accum += atof( D[j][f] );
  538.         if( accum == 0.0 ) continue;
  539.         for( j = 0; j < N_d_rows; j++ )  /* compute percentages and replace */
  540.             sprintf( D[j][f], "%f", (atof( D[j][f] ) / accum ) * 100 );
  541.         }
  542.     /* fprintf( stderr, "Percents have been calculated.  The new data is:\n" );
  543.     for( i = 0; i < N_d_rows; i++ ) {
  544.         for( j = 0; j < N_d_fields; j++ ) fprintf( stderr, "%12s ", D[i][j] );
  545.         fprintf( stderr, "\n" );
  546.         }
  547.     */
  548.     }
  549. }
  550. SHAR_EOF
  551. ############################
  552.  
  553. cat << SHAR_EOF > src/gget.c
  554. /* Given a parm name, returns a value.  Searches these places for the value:
  555.    first: Chunk; second: Ichunk; third: templates.
  556.    Handles "$1 $2.." values which become command line args.
  557.    Notes: 
  558.     Multi-line values are returned with lines delimited by '\n'.
  559.     All white space at beginning and end of value is stripped off.
  560.     Master template values can be multi-line.
  561. */
  562. #include <ctype.h>
  563. #include "template.h"
  564. #include "gdp.x"
  565.  
  566.  
  567. gget( value, parm )
  568. char value[], parm[];
  569. {
  570. int i, ix, ufound, mfound, inln, k, index, j, l;
  571. char p[40], proc[40], constraint[80], foo[40], name[30];
  572. static char linebuf[INWIDTH], lastproc[30]="";
  573. static int start, stop;
  574. inln = 0;
  575.  
  576. /* check user spec file */
  577. if( Clines < 1 ) { fprintf( stderr, "gget: No chunk exists.\n" ); gdp_exit(); }
  578.  
  579. ufound = 0;
  580. for( k = 0; k < Clines; k++ ) {      /* search Chunk for parm entry */
  581.     inln++;
  582.     if( sscanf( Chunk[k], "%s", p ) < 1 ) continue; /* blank lines */
  583.     if( p[0] == '#' || p[0] == ':' ) continue; /* comments */
  584.     if( !is_parm_name( p )) continue;     /* non-parm lines */
  585.     p[ strlen( p ) - 1 ] = '\0';    /* get rid of colon */
  586.  
  587.     if( strcmp( parm, p )==0 ) {  /* found the parm entry.. */
  588.         ix = 0;
  589.         getfld( linebuf, Chunk[k], &ix ); /* get first field-- not needed */
  590.         strcpy( linebuf, &(Chunk[k][ix]) ); /* get value */
  591.         strip_ws( linebuf );
  592.  
  593.         /* command line subst. */
  594.         if( linebuf[0] == '$' ) cmdline_subst( linebuf );
  595.  
  596.         strcpy( value, linebuf );
  597.  
  598.         /* get additional lines, if any */
  599.         while( k < Clines-1 ) {
  600.             k++;
  601.             strcpy( linebuf, Chunk[ k ] );
  602.             strip_ws( linebuf );
  603.             if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
  604.             if( linebuf[0] == '$' ) cmdline_subst( linebuf );
  605.             
  606.             sscanf( linebuf, "%s", p );
  607.             if( is_parm_name( p )) break;
  608.  
  609.             /* get rid of backslashes in text */
  610.             for( j = 0, l = 0; j < strlen( linebuf ); j++ ) 
  611.                 if( linebuf[j] != '\134' ) linebuf[l++] = linebuf[j];
  612.             linebuf[l] = '\0';
  613.  
  614.             if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
  615.                 fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ ); 
  616.                 gdp_exit(); 
  617.                 }
  618.             else sprintf( value, "%s\n%s", value, linebuf );
  619.             }
  620.         ufound = 1;
  621.         break;
  622.         }
  623.     }
  624.  
  625.  
  626. /* if not found in user spec, and there is an inherit file defined, check there */
  627. if( !ufound && Ilines > 0 ) {  
  628.     for( k = 0; k < Ilines; k++ ) {
  629.         sscanf( Ichunk[k], "%s", p );
  630.         if( p[0] == '#' || p[0] == ':' ) continue;
  631.         if( !is_parm_name( p )) continue;
  632.         p[ strlen( p ) - 1 ] = '\0';/* get rid of colon */
  633.         if( strcmp( parm, p )==0 ) {
  634.             ix = 0;
  635.             getfld( linebuf, Ichunk[k], &ix ); /* get first field-- not needed */
  636.             strcpy( linebuf, &(Ichunk[k][ix]) ); /* get value */
  637.             strip_ws( linebuf );
  638.     
  639.             /* command line subst. */
  640.             if( linebuf[0] == '$' ) cmdline_subst( linebuf );
  641.  
  642.             strcpy( value, linebuf );
  643.     
  644.             /* get additional lines, if any */
  645.             while( k < Ilines-1 ) {
  646.                 k++;
  647.                 strcpy( linebuf, Ichunk[ k ] );
  648.                 strip_ws( linebuf );
  649.                 if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
  650.                 if( linebuf[0] == '$' ) cmdline_subst( linebuf );
  651.                 
  652.                 sscanf( linebuf, "%s", p );
  653.                 if( is_parm_name( p )) break;
  654.  
  655.                 /* get rid of backslashes in text */
  656.                 for( j = 0, l = 0; j < strlen( linebuf ); j++ ) 
  657.                     if( linebuf[j] != '\134' ) linebuf[l++] = linebuf[j];
  658.                 linebuf[l] = '\0';
  659.  
  660.                 if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
  661.                     fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ); 
  662.                     gdp_exit(); 
  663.                     }
  664.                 else sprintf( value, "%s\n%s", value, linebuf );
  665.                 }
  666.             ufound = 1;
  667.             break;
  668.             }
  669.         }
  670.     }
  671.     
  672. /* if still not found, or if type checking turned on, check master template */
  673. if( !ufound || Do_cons_check ) {  
  674.     
  675.     /* get proc name */
  676.     sscanf( Chunk[0], "%*s %s", proc ); 
  677.     proc[ strlen( proc )-1 ] = '\0';
  678.  
  679.     /* find where proc starts in storage */
  680.     if( strcmp( proc, lastproc )!= 0 ) {
  681.         strcpy( lastproc, proc );
  682.         index = 0;
  683.         for( k = 0; ; k++ ) {
  684.             if( k > 0 && Tdx[k] == 0 ) { fprintf( stderr, "%s: Proc has no template.\n", proc ); gdp_exit(); }
  685.             index += Tdx[k];
  686.             sscanf( Template[ index ], "%*s %s", p );
  687.             p[ strlen( p ) -1 ] = '\0';
  688.             if( strcmp( proc, p )==0 ) {
  689.                 start = index;
  690.                 stop = start + Tdx[k+1];
  691.                 start ++;  /* adjust to skip over Proc line */
  692.                 break;
  693.                 }
  694.             }
  695.         }
  696.     
  697.     mfound = 0;
  698.     for( k = start; k < stop; k++ ) {
  699.         sscanf( Template[k], "%s", p );
  700.         if( p[0] == '#' || p[0] == ':' ) continue;
  701.         if( !is_parm_name( p )) continue;
  702.         p[ strlen( p ) -1 ] = '\0'; /* get rid of colon */
  703.         if( strcmp( parm, p )==0 ) {
  704.             ix = 0;
  705.             getfld( linebuf, Template[k], &ix ); /* get first field-- not needed */
  706.             getfld( constraint, Template[k], &ix );
  707.             if( !ufound ) {
  708.                 getfld( linebuf, Template[k], &ix ); /* get value */
  709.  
  710.                 strcpy( value, linebuf );
  711.                 }
  712.     
  713.             /* get additional lines, if any */
  714.             while( k < stop ) {
  715.                 k++;
  716.                 strcpy( linebuf, Template[k] );
  717.                 strip_ws( linebuf );
  718.                 if( linebuf[0] == ':' || linebuf[0] == '#' ) continue;
  719.                 if( linebuf[0] == '$' ) cmdline_subst( linebuf );
  720.                 sscanf( linebuf, "%s", p );
  721.                 if( is_parm_name( p )) break;
  722.                 if( strlen( value ) + strlen( linebuf ) > HBUFSIZ-1 ) {
  723.                     fprintf( stderr, "%s: multi-line text too long (max=%d).\n", parm, HBUFSIZ ); 
  724.                     gdp_exit(); 
  725.                     }
  726.                 else sprintf( value, "%s\n%s", value, linebuf );
  727.                 }
  728.             mfound = 1;
  729.             break;
  730.             }
  731.         }
  732.     
  733.     if( mfound ) {
  734.         if( ! constraint_check( value, constraint ) ) { 
  735.             fprintf( stderr, "parm %s Line %d in proc %s.\n", parm, inln, proc ); 
  736.             gdp_exit(); 
  737.             }
  738.         strcpy( Last_constraint, constraint );
  739.         }
  740.     else    {
  741.         fprintf( stderr, "Parameter '%s' not found. Line %d in proc %s.\n", parm, inln, proc ); 
  742.         gdp_exit();
  743.         }
  744.     
  745.     }
  746. /* always returns here (except error exit) */
  747. strip_ws( value );
  748.  
  749. /* trap for debugging @/
  750. * if( strcmp( parm, "Subtitle.above" )==0 ) {
  751. *    fprintf( stderr, "$%s$", value );
  752. *    for( i = 0; i < Clines; i++ ) fprintf( stderr, "%s", Chunk[i] );
  753. *    fprintf( stderr, "###\n" );
  754. *    for( i = 0; i < Ilines; i++ ) fprintf( stderr, "%s", Ichunk[i] );
  755. *    fprintf( stderr, "&&&\n" );
  756. *    }
  757. */
  758.  
  759. return( 1 );
  760. }
  761.  
  762.  
  763.  
  764.  
  765. /* ====================================== */
  766. /* changes val to command line argument if value is $n ($1, $2, etc) */
  767. cmdline_subst( val )
  768. char val[];
  769. {
  770. if( val[0] == '$' && atoi( &val[1] ) > 0 ) { 
  771.     if( atoi( &val[1] ) > Argc-1 ) { fprintf( stderr, "%s: not that many arguments\n", val ); gdp_exit(); }
  772.     strcpy( val, Arg[ atoi( &val[1] ) ] );
  773.     }
  774. }
  775. /* ===================================== */
  776. /* returns true if s is in parameter name format
  777.    or if "Proc"
  778. */
  779. is_parm_name( s )
  780. char s[];
  781. {
  782. int l;
  783. l = strlen( s );
  784. if( isupper( s[0] ) && s[ l-1 ] == ':' && s[ l-2 ] != '\134' ) return( 1 );
  785. else if( strcmp( s, "Proc" )==0 ) return( 1 );
  786. else return( 0 );
  787. }
  788. SHAR_EOF
  789. ############################
  790.  
  791. cat << SHAR_EOF > src/graphic.c
  792. /* small, lowlevel routines for graphics */
  793. #include "graphic.h"
  794.  
  795. /* linear, log, time, yymm, mmddyy, polar */
  796.  
  797. /* =========================== */
  798. /* for setting up scaling in x */
  799. setscale_x( xlow, xhi, datalow, datahi )
  800. double     xlow,     /* absolute x location of left side of the area */
  801.     xhi,     /* absolute x location of the right side of the area */
  802.     datalow, /* data-units x at the left side */
  803.     datahi;     /* data-units x at the right side */
  804. {
  805. Xlo = xlow;
  806. Xhi = xhi;
  807. DXlo = datalow;
  808. DXhi = datahi;
  809. if( datahi-datalow <= 0 || xhi-xlow <= 0 ) fprintf( stderr, "wild" );
  810. if( Scale_discipline_x == LINEAR )Scale_x = (xhi-xlow) / (datahi-datalow) ;
  811. else if( Scale_discipline_x == LOG )Scale_x = (xhi-xlow) / log( datahi-datalow ) ;
  812. else if( Scale_discipline_x == YYMM ) {
  813.     Scale_x = (xhi-xlow) / ( yymm_to_i( datahi ) - yymm_to_i( datalow ));
  814.     DXlo = yymm_to_i( datalow );
  815.     DXhi = yymm_to_i( datahi );
  816.     }
  817. }
  818.  
  819. /* =========================== */
  820. /* for setting up scaling in y */
  821. setscale_y( ylow, yhi, datalow, datahi )
  822. double     ylow,     /* absolute y location of low side of the area */
  823.     yhi,     /* absolute y location of high side of the area */
  824.     datalow, /* data-units y at the low side */
  825.     datahi;     /* data-units y at the high side */
  826. {
  827. Ylo = ylow;
  828. Yhi = yhi;
  829. DYlo = datalow;
  830. DYhi = datahi;
  831. if( datahi-datalow <= 0 || yhi-ylow <= 0 ) fprintf( stderr, "wild" );
  832. if( Scale_discipline_y == LINEAR )Scale_y = (yhi-ylow) / (datahi-datalow) ;
  833. else if( Scale_discipline_y == LOG )Scale_y = (yhi-ylow) / log( datahi-datalow ) ;
  834. }
  835.  
  836. /* =========================== */
  837. /* returns an absolute x location from a data value */
  838. double da_x( d )
  839. double d;
  840. {
  841. double f;
  842. if( Scale_discipline_x == LINEAR ) return( Xlo + (( d - DXlo ) * Scale_x ));
  843. else if( Scale_discipline_x == LOG ) { 
  844.     if( d-DXlo > 0.0 )return( Xlo + ( log( d - DXlo )*Scale_x )); 
  845.     else return( Xlo );
  846.     }
  847. else if( Scale_discipline_x == YYMM ) {
  848.     if( d >= 7000 ) d = yymm_to_i( d );
  849.     return( Xlo + (( d - DXlo) * Scale_x ));
  850.     }
  851. }
  852.  
  853. /* =========================== */
  854. /* returns an absolute y location from a data value */
  855. double da_y( d )
  856. double d;
  857. {
  858. if( Scale_discipline_y == LINEAR ) return( Ylo + (( d - DYlo ) * Scale_y ));
  859. else if( Scale_discipline_y == LOG ) {
  860.     if( d-DYlo > 0.0 )return( Ylo + ( log( d - DYlo )*Scale_y ));
  861.     else return( Ylo );
  862.     }
  863. }
  864.  
  865.  
  866. /* =========================== */
  867. /* returns a data x location from an abs value */
  868. double ab_x( d )
  869. double d;
  870. {
  871. if( Scale_discipline_x == LINEAR ) return( ( d - da_x( 0.0 ) ) / Scale_x );
  872. else if( Scale_discipline_x == LOG ) return( exp( (d-Xlo) / Scale_x ) );
  873. }
  874.  
  875.  
  876. /* =========================== */
  877. /* returns a data y location from an abs value */
  878. double ab_y( d )
  879. double d;
  880. {
  881. if( Scale_discipline_y == LINEAR ) return( ( d - da_y( 0.0 ) ) / Scale_y );
  882. else if( Scale_discipline_y == LOG ) return( exp( (d-Ylo) / Scale_y ) );
  883. }
  884.  
  885.  
  886. /* ============================ */
  887. /* Returns an integer given a YYMM date.  Jan 1970 is zero. */
  888.  
  889. yymm_to_i( m )
  890. double m;
  891. {
  892. int yr, mo;
  893.  
  894. yr = (int)(m) / 100;
  895. if( yr < 70 ) yr += 100;
  896. mo = (int)(m) % 100;
  897. return( ((yr-70)*12 ) + mo );
  898. }
  899.  
  900. SHAR_EOF
  901. ############################
  902.  
  903. cat << SHAR_EOF > src/graphic.d
  904. /* NT calls - these calls are the graphics primatives */
  905. /* Notes:    Calls to NTtext should be always preceded by an NTmov() call.
  906. */
  907. #include <stdio.h>
  908. #include <math.h>
  909. #include <strings.h>
  910.  
  911. #define YES 1
  912. #define NO 0
  913.  
  914. /* move to x, y absolute */
  915. #define NTmov( x , y )        pcode( 'M', (double)x , (double)y, "" )
  916.  
  917. /* line to x, y absolute */
  918. #define NTlin( x , y )        pcode( 'L', (double)x , (double)y, "" )
  919.  
  920. /* move to x, y data */
  921. #define NTm( x , y )        pcode( 'M', da_x((double) x ) , da_y((double) y ), "" )
  922.  
  923. /* line to x, y data */
  924. #define NTl( x , y )        pcode( 'L', da_x((double) x ) , da_y((double) y ), "" )
  925.  
  926. /* path to x, y absolute (form a polygon to be shaded later) */
  927. #define NTpath( x , y )        pcode( 'P', (double)x , (double)y, "" )
  928.  
  929. /* path to x, y data (form a polygon to be shaded later) */
  930. #define NTp( x , y )        pcode( 'P', da_x((double) x ) , da_y((double) y ), "" )
  931.  
  932. /* do shading, within the previously defined polygon path.. the shade can be 0 to 1 */
  933. #define NTshade( x )        pcode( 'S', (double)x , 0.0, "" )
  934.  
  935. /* do shading, within the previously defined rectangle path.. the shade can be 0 to 1 */
  936. #define NTrectangle( x )    pcode( 'E', (double)x, 0.0, "" ); 
  937.  
  938. /* text string s starting at the current location  */
  939. #define NTtext( s )        pcode( 'T', 0.0, 0.0, s )
  940.  
  941. /* use font s */
  942. #define NTfont( s )        { if( strlen( s ) < 1 ) { pcode( 'F', 0.0, 0.0, Stdfont ); } \
  943.                     else { pcode( 'F', 0.0, 0.0, s ); } }
  944.  
  945. /* use point size x, current font */
  946. #define NTptsize( x )        { pcode( 'I', (double)x , 0.0, "" ); Chsz = x; Chh = (x+2)/72.0; }
  947.  
  948. /* change the char direction x degrees counterclockwise */
  949. #define NTchardir( x )        { pcode( 'D', (double)x , 0.0, "" ); Chd = x ; }
  950.  
  951. /* center text bewteen current location and a point w ABSOLUTE units away in the current text direction */
  952. #define NTcentext( s , w )    pcode( 'C', (double)w , 0.0, s )
  953.  
  954. /* right justify text bewteen curr loc and a point w ABSOLUTE units away in the current text direction */
  955. #define NTrightjust( s, w )    pcode( 'J', (double)w, 0.0, s )
  956.  
  957.  
  958. /* select paper orientation (0 = portrait, 1 = landscape) */
  959. #define NTpaper( x )        { Paper = (int) (x); pcode( 'O', (double)x , 0.0, "" ); }
  960.  
  961. /* select line attributes-- dash pattern string, line width, dash magnifier  */
  962. #define NTlinetype( s, x, y )    { pcode( 'Y', (double)x , (double)y, s ); Lw = x; }
  963. /* reset line attributes to "standard" solid line */
  964. #define NTnormline()        { pcode( 'Y', StdLw, 1.0, "0" ); Lw = StdLw; }
  965.  
  966. /* select color */
  967. #define NTcolor( x , y )    pcode( 'R', (double)x , (double)y, "" )
  968.  
  969. /* eject page (printers), end-of-plot (screens) */
  970. #define NTshow()        pcode( 'Z', 0.0, 0.0, "" )
  971.  
  972. /* wait for user input */
  973. #define NTwait()        pcode( 'W', 0.0, 0.0, "" )
  974.  
  975. /* put these around repetitive drawing operations to improve efficiency */
  976. #define NTbatch_on()        pcode( 'B', 0.0, 0.0, "" )
  977. #define NTbatch_off()        pcode( 'b', 0.0, 0.0, "" )
  978.  
  979. /* turn clipping to current area on/off */
  980. #define NTclip_on()        pcode( 'K', 0.0, 0.0, "" );
  981. #define NTclip_off()        pcode( 'k', 0.0, 0.0, "" );
  982.  
  983. /* 
  984. Graphics notes:
  985.  
  986. - Origin is in lower left corner of "paper", regardless of orientation of paper.
  987. - User units are inches.  All values are positive.
  988. - Icode quads are passed to the IPL device interpreters.
  989. - Format of i-code will be: "a x y s\n", where a is an op code, x and y
  990.    are coordinates in inches, and s is a variable length string (may be null).
  991. - Op codes are:        M x y    =moveto x,y
  992.             L x y    =lineto x,y
  993.             P x y    =pathto x,y (for defining shade area)
  994.             S s     =shade within path using shade s
  995.             T 0 0 s    =text string s at current position
  996.             F p 0 f =use font f (point size p)
  997.             I p 0     =use point-size p 
  998.             D x 0    =text-direction in x degrees counter-clockwise
  999.                C w 0    =center text between current point for distance w
  1000.             J w 0    =right-justify text between current point for distance w
  1001.             O i    =paper orientation, i=0 portrait, i=1 landscape 
  1002.             Y w p d =line type, w = width, p = dash pattern density, d = dash pattern
  1003.             R r g b =color r,g,b (later, if ever)
  1004.             Z    =finished, show page 
  1005.           (0 indicates "don't care" )
  1006. Notes:
  1007. - Set up for one-way communication w/printers, meaning application gets no
  1008.   feedback from printer.  This is so that the system will function properly in
  1009.   environments where printers are spooled.  Workstation drivers may, however,
  1010.   be interactive (two-way).
  1011.  
  1012. - Line type operator allows specification of different drawing line widths and dash
  1013.    patterns.  NTlinetype( S, X, Y) where: X = line width;  Y = dash pattern 
  1014.    magnification (0.1 to 10).  S indicates dash pattern.  If S is "0", an unbroken 
  1015.    (normal) line is produced.  If S is "1" through "8", a preset dash pattern is used.  
  1016.    Otherwise, S is assumed to hold the dash pattern string "[ n1 n2 n3.. ]".
  1017.  
  1018. - There should be no other NT routine calls between an NTtext call and it's preceding NTmov.  
  1019.    Set fonts and point sizes before moving to the location, then do the move, then do the text.
  1020.    There is no problem if using the current position for text (i.e. not doing a move).
  1021. */
  1022.  
  1023. #define LINEAR 0
  1024. #define LOG 1
  1025. #define YYMM 2
  1026.  
  1027. #define WHITE 1
  1028. #define BLACK 0
  1029. extern double da_x(), da_y(), ab_x(), ab_y();
  1030.  
  1031. SHAR_EOF
  1032. ############################
  1033.  
  1034. cat << SHAR_EOF > src/graphic.h
  1035. #include "graphic.d"
  1036. /***** internal graphics parameters *****/
  1037. double Xlo, Xhi, Ylo, Yhi;        /* graphic area bounds, absolute coords */
  1038. double DXlo, DXhi, DYlo, DYhi;        /* graphic area bounds, data coords */
  1039. double Scale_x = 1, Scale_y = 1;         /* linear scaling factors in x and y */
  1040. int Scale_discipline_x = LINEAR;    /* either LINEAR or LOG */
  1041. int Scale_discipline_y = LINEAR;    /* either LINEAR or LOG */
  1042. SHAR_EOF
  1043. ############################
  1044.  
  1045. cat << SHAR_EOF > src/graphic.x
  1046. #include "graphic.d"
  1047. /***** internal graphics parameters *****/
  1048. extern double Xlo, Xhi, Ylo, Yhi;        /* graphic area bounds, absolute coords */
  1049. extern double DXlo, DXhi, DYlo, DYhi;        /* graphic area bounds, data coords */
  1050. extern double Scale_x, Scale_y;         /* linear scaling factors in x and y */
  1051. extern int Scale_discipline_x;            /* either LINEAR or LOG */
  1052. extern int Scale_discipline_y;            /* either LINEAR or LOG */
  1053. SHAR_EOF
  1054. ############################
  1055.  
  1056.  
  1057.