00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #define DEBUG
00032
00033 #define NEED_PLDEBUG
00034 #include "plplotP.h"
00035 #ifdef macintosh
00036 #include "mac.h"
00037
00038 #endif
00039
00040 #ifdef DJGPP // dos386/djgpp
00041 #ifdef __unix
00042 #undef __unix
00043 #endif
00044 #endif
00045
00046 #ifdef __unix
00047 #include <sys/types.h>
00048 #include <sys/stat.h>
00049 #ifdef PL_HAVE_UNISTD_H
00050 #include <unistd.h>
00051 #endif
00052 #include <errno.h>
00053 #endif
00054
00055
00056 #include "mt19937ar.h"
00057
00058 #define BUFFER_SIZE 256
00059 #define COLLEN 30
00060 #define PALLEN 160
00061 #define MSGLEN 1024
00062
00063
00064
00065 #define FUZZ_EPSILON 1.e-4
00066
00067
00068
00069
00070 char PLDLLIMPEXP * plplotLibDir = 0;
00071
00072 static void
00073 color_set( PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, char *name );
00074
00075 static void
00076 strcat_delim( char *dirspec );
00077
00078 static int
00079 ( *exit_handler )( const char *errormsg );
00080
00081 static void
00082 ( *abort_handler )( const char *errormsg );
00083
00084 static void
00085 plcmap0_def( int imin, int imax );
00086
00087 static void
00088 plcmap1_def( void );
00089
00090 static PLFLT
00091 value( double n1, double n2, double hue );
00092
00093 static char *
00094 read_line( char *buffer, int length, FILE *fp );
00095
00096 static void
00097 cmap0_palette_read( const char *filename,
00098 int *number_colors, int **r, int **g, int **b, double **a );
00099
00100
00101
00102 #if defined ( DJGPP )
00103 #ifndef PLLIBDEV
00104 #define PLLIBDEV "c:/plplot/lib"
00105 #endif
00106
00107 #elif defined ( MSDOS )
00108 #ifndef PLLIBDEV
00109 #define PLLIBDEV "c:\\plplot\\lib"
00110 #endif
00111
00112 #else
00113
00114
00115
00116 #ifndef PLLIBDEV
00117 #define PLLIBDEV "/usr/local/plplot/lib"
00118 #endif
00119
00120 #endif
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132 void
00133 c_plcol0( PLINT icol0 )
00134 {
00135 if ( plsc->level < 1 )
00136 {
00137 plabort( "plcol0: Please call plinit first" );
00138 return;
00139 }
00140 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
00141 {
00142 char buffer[BUFFER_SIZE];
00143 snprintf( buffer, BUFFER_SIZE, "plcol0: Invalid color map entry: %d", (int) icol0 );
00144 plabort( buffer );
00145 return;
00146 }
00147
00148 plsc->icol0 = icol0;
00149 plsc->curcolor.r = plsc->cmap0[icol0].r;
00150 plsc->curcolor.g = plsc->cmap0[icol0].g;
00151 plsc->curcolor.b = plsc->cmap0[icol0].b;
00152 plsc->curcolor.a = plsc->cmap0[icol0].a;
00153
00154 plsc->curcmap = 0;
00155 plP_state( PLSTATE_COLOR0 );
00156 }
00157
00158
00159
00160
00161
00162
00163
00164 void
00165 c_plcol1( PLFLT col1 )
00166 {
00167 PLINT icol1;
00168
00169 if ( plsc->level < 1 )
00170 {
00171 plabort( "plcol1: Please call plinit first" );
00172 return;
00173 }
00174 if ( col1 < 0 || col1 > 1 || isnan( col1 ) )
00175 {
00176 char buffer[BUFFER_SIZE];
00177 snprintf( buffer, BUFFER_SIZE, "plcol1: Invalid color map position: %f", (PLFLT) col1 );
00178 plabort( buffer );
00179 return;
00180 }
00181
00182 icol1 = (PLINT) ( col1 * plsc->ncol1 );
00183 icol1 = MIN( icol1, plsc->ncol1 - 1 );
00184
00185 plsc->icol1 = icol1;
00186 plsc->curcolor.r = plsc->cmap1[plsc->icol1].r;
00187 plsc->curcolor.g = plsc->cmap1[plsc->icol1].g;
00188 plsc->curcolor.b = plsc->cmap1[plsc->icol1].b;
00189 plsc->curcolor.a = plsc->cmap1[plsc->icol1].a;
00190
00191 plsc->curcmap = 1;
00192 plP_state( PLSTATE_COLOR1 );
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 void
00202 c_plscolbg( PLINT r, PLINT g, PLINT b )
00203 {
00204 plscol0( 0, r, g, b );
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 void
00214 c_plscolbga( PLINT r, PLINT g, PLINT b, PLFLT a )
00215 {
00216 plscol0a( 0, r, g, b, a );
00217 }
00218
00219
00220
00221
00222
00223
00224
00225 void
00226 c_plgcolbg( PLINT *r, PLINT *g, PLINT *b )
00227 {
00228 plgcol0( 0, r, g, b );
00229 }
00230
00231
00232
00233
00234
00235
00236
00237 void
00238 c_plgcolbga( PLINT *r, PLINT *g, PLINT *b, PLFLT *a )
00239 {
00240 plgcol0a( 0, r, g, b, a );
00241 }
00242
00243
00244
00245
00246
00247
00248
00249
00250 void
00251 c_plscol0( PLINT icol0, PLINT r, PLINT g, PLINT b )
00252 {
00253 if ( plsc->cmap0 == NULL )
00254 plscmap0n( 0 );
00255 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
00256 {
00257 char buffer[BUFFER_SIZE];
00258 snprintf( buffer, BUFFER_SIZE, "plscol0: Illegal color table value: %d", (int) icol0 );
00259 plabort( buffer );
00260 return;
00261 }
00262 if ( ( r < 0 || r > 255 ) || ( g < 0 || g > 255 ) || ( b < 0 || b > 255 ) )
00263 {
00264 char buffer[BUFFER_SIZE];
00265 snprintf( buffer, BUFFER_SIZE, "plscol0: Invalid RGB color: %d, %d, %d",
00266 (int) r, (int) g, (int) b );
00267 plabort( buffer );
00268 return;
00269 }
00270
00271 plscol0a( icol0, r, g, b, 1.0 );
00272 }
00273
00274
00275
00276
00277
00278
00279
00280
00281 void
00282 c_plscol0a( PLINT icol0, PLINT r, PLINT g, PLINT b, PLFLT a )
00283 {
00284 if ( plsc->cmap0 == NULL )
00285 plscmap0n( 0 );
00286 if ( icol0 < 0 || icol0 >= plsc->ncol0 )
00287 {
00288 char buffer[BUFFER_SIZE];
00289 snprintf( buffer, BUFFER_SIZE, "plscol0a: Illegal color table value: %d", (int) icol0 );
00290 plabort( buffer );
00291 return;
00292 }
00293 if ( ( r < 0 || r > 255 ) || ( g < 0 || g > 255 ) || ( b < 0 || b > 255 ) || ( a < 0 || a > 1.0 ) )
00294 {
00295 char buffer[BUFFER_SIZE];
00296 snprintf( buffer, BUFFER_SIZE, "plscol0a: Invalid RGB color: %d, %d, %d, %f",
00297 (int) r, (int) g, (int) b, (double) a );
00298 plabort( buffer );
00299 return;
00300 }
00301
00302 plsc->cmap0[icol0].r = r;
00303 plsc->cmap0[icol0].g = g;
00304 plsc->cmap0[icol0].b = b;
00305 plsc->cmap0[icol0].a = a;
00306
00307 if ( plsc->level > 0 )
00308 plP_state( PLSTATE_CMAP0 );
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318 void
00319 c_plgcol0( PLINT icol0, PLINT *r, PLINT *g, PLINT *b )
00320 {
00321 if ( plsc->cmap0 == NULL )
00322 plscmap0n( 0 );
00323
00324 *r = -1;
00325 *g = -1;
00326 *b = -1;
00327
00328 if ( icol0 < 0 || icol0 > plsc->ncol0 )
00329 {
00330 char buffer[BUFFER_SIZE];
00331 snprintf( buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d", (int) icol0 );
00332 plabort( buffer );
00333 return;
00334 }
00335
00336 *r = plsc->cmap0[icol0].r;
00337 *g = plsc->cmap0[icol0].g;
00338 *b = plsc->cmap0[icol0].b;
00339
00340 return;
00341 }
00342
00343
00344
00345
00346
00347
00348
00349
00350 void
00351 c_plgcol0a( PLINT icol0, PLINT *r, PLINT *g, PLINT *b, PLFLT *a )
00352 {
00353 if ( plsc->cmap0 == NULL )
00354 plscmap0n( 0 );
00355
00356 *r = -1;
00357 *g = -1;
00358 *b = -1;
00359 *a = -1.0;
00360
00361 if ( icol0 < 0 || icol0 > plsc->ncol0 )
00362 {
00363 char buffer[BUFFER_SIZE];
00364 snprintf( buffer, BUFFER_SIZE, "plgcol0: Invalid color index: %d", (int) icol0 );
00365 plabort( buffer );
00366 return;
00367 }
00368
00369 *r = plsc->cmap0[icol0].r;
00370 *g = plsc->cmap0[icol0].g;
00371 *b = plsc->cmap0[icol0].b;
00372 *a = plsc->cmap0[icol0].a;
00373
00374 return;
00375 }
00376
00377
00378
00379
00380
00381
00382
00383
00384 void
00385 c_plscmap0( const PLINT *r, const PLINT *g, const PLINT *b, PLINT ncol0 )
00386 {
00387 int i;
00388
00389 plscmap0n( ncol0 );
00390
00391 for ( i = 0; i < plsc->ncol0; i++ )
00392 {
00393 if ( ( r[i] < 0 || r[i] > 255 ) ||
00394 ( g[i] < 0 || g[i] > 255 ) ||
00395 ( b[i] < 0 || b[i] > 255 ) )
00396 {
00397 char buffer[BUFFER_SIZE];
00398 snprintf( buffer, BUFFER_SIZE, "plscmap0: Invalid RGB color: %d, %d, %d",
00399 (int) r[i], (int) g[i], (int) b[i] );
00400 plabort( buffer );
00401 return;
00402 }
00403
00404 plsc->cmap0[i].r = r[i];
00405 plsc->cmap0[i].g = g[i];
00406 plsc->cmap0[i].b = b[i];
00407 plsc->cmap0[i].a = 1.0;
00408 }
00409
00410 if ( plsc->level > 0 )
00411 plP_state( PLSTATE_CMAP0 );
00412 }
00413
00414
00415
00416
00417
00418
00419
00420
00421 void
00422 c_plscmap0a( const PLINT *r, const PLINT *g, const PLINT *b, const PLFLT *a, PLINT ncol0 )
00423 {
00424 int i;
00425
00426 plscmap0n( ncol0 );
00427
00428 for ( i = 0; i < plsc->ncol0; i++ )
00429 {
00430 if ( ( r[i] < 0 || r[i] > 255 ) ||
00431 ( g[i] < 0 || g[i] > 255 ) ||
00432 ( b[i] < 0 || b[i] > 255 ) ||
00433 ( a[i] < 0.0 || a[i] > 1.0 ) )
00434 {
00435 char buffer[BUFFER_SIZE];
00436 snprintf( buffer, BUFFER_SIZE, "plscmap0a: Invalid RGB color: %d, %d, %d, %f",
00437 (int) r[i], (int) g[i], (int) b[i], (double) a[i] );
00438 plabort( buffer );
00439 return;
00440 }
00441
00442 plsc->cmap0[i].r = r[i];
00443 plsc->cmap0[i].g = g[i];
00444 plsc->cmap0[i].b = b[i];
00445 plsc->cmap0[i].a = a[i];
00446 }
00447
00448 if ( plsc->level > 0 )
00449 plP_state( PLSTATE_CMAP0 );
00450 }
00451
00452
00453
00454
00455
00456
00457
00458
00459 void
00460 c_plscmap1( const PLINT *r, const PLINT *g, const PLINT *b, PLINT ncol1 )
00461 {
00462 int i;
00463
00464 plscmap1n( ncol1 );
00465
00466 for ( i = 0; i < plsc->ncol1; i++ )
00467 {
00468 if ( ( r[i] < 0 || r[i] > 255 ) ||
00469 ( g[i] < 0 || g[i] > 255 ) ||
00470 ( b[i] < 0 || b[i] > 255 ) )
00471 {
00472 char buffer[BUFFER_SIZE];
00473 snprintf( buffer, BUFFER_SIZE, "plscmap1: Invalid RGB color: %d, %d, %d",
00474 (int) r[i], (int) g[i], (int) b[i] );
00475 plabort( buffer );
00476 return;
00477 }
00478 plsc->cmap1[i].r = r[i];
00479 plsc->cmap1[i].g = g[i];
00480 plsc->cmap1[i].b = b[i];
00481 plsc->cmap1[i].a = 1.0;
00482 }
00483
00484 if ( plsc->level > 0 )
00485 plP_state( PLSTATE_CMAP1 );
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495 void
00496 c_plscmap1a( const PLINT *r, const PLINT *g, const PLINT *b, const PLFLT *a, PLINT ncol1 )
00497 {
00498 int i;
00499
00500 plscmap1n( ncol1 );
00501
00502 for ( i = 0; i < plsc->ncol1; i++ )
00503 {
00504 if ( ( r[i] < 0 || r[i] > 255 ) ||
00505 ( g[i] < 0 || g[i] > 255 ) ||
00506 ( b[i] < 0 || b[i] > 255 ) ||
00507 ( a[i] < 0.0 || a[i] > 1.0 ) )
00508 {
00509 char buffer[BUFFER_SIZE];
00510 snprintf( buffer, BUFFER_SIZE, "plscmap1a: Invalid RGB color: %d, %d, %d, %f",
00511 (int) r[i], (int) g[i], (int) b[i], (double) a[i] );
00512 plabort( buffer );
00513 return;
00514 }
00515 plsc->cmap1[i].r = r[i];
00516 plsc->cmap1[i].g = g[i];
00517 plsc->cmap1[i].b = b[i];
00518 plsc->cmap1[i].a = a[i];
00519 }
00520
00521 if ( plsc->level > 0 )
00522 plP_state( PLSTATE_CMAP1 );
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576 void
00577 c_plscmap1l( PLINT itype, PLINT npts, const PLFLT *pos,
00578 const PLFLT *coord1, const PLFLT *coord2, const PLFLT *coord3, const PLINT *rev )
00579 {
00580 int n;
00581 PLFLT h, l, s, r, g, b;
00582
00583 if ( npts < 2 )
00584 {
00585 plabort( "plscmap1l: Must specify at least two control points" );
00586 return;
00587 }
00588
00589 if ( ( pos[0] != 0 ) || ( pos[npts - 1] != 1 ) )
00590 {
00591 plabort( "plscmap1l: First, last control points must lie on boundary" );
00592 return;
00593 }
00594
00595 if ( npts > PL_MAX_CMAP1CP )
00596 {
00597 plabort( "plscmap1l: exceeded maximum number of control points" );
00598 return;
00599 }
00600
00601
00602
00603 if ( plsc->cmap1 == NULL )
00604 plscmap1n( 0 );
00605
00606
00607
00608 plsc->ncp1 = npts;
00609
00610 for ( n = 0; n < npts; n++ )
00611 {
00612 if ( itype == 0 )
00613 {
00614 h = coord1[n];
00615 l = coord2[n];
00616 s = coord3[n];
00617 }
00618 else
00619 {
00620 r = coord1[n];
00621 g = coord2[n];
00622 b = coord3[n];
00623 c_plrgbhls( r, g, b, &h, &l, &s );
00624 }
00625
00626 plsc->cmap1cp[n].h = h;
00627 plsc->cmap1cp[n].l = l;
00628 plsc->cmap1cp[n].s = s;
00629 plsc->cmap1cp[n].p = pos[n];
00630 plsc->cmap1cp[n].a = 1.0;
00631
00632 if ( rev == NULL )
00633 plsc->cmap1cp[n].rev = 0;
00634 else
00635 plsc->cmap1cp[n].rev = rev[n];
00636 }
00637
00638
00639
00640 plcmap1_calc();
00641 }
00642
00643
00644
00645
00646
00647
00648
00649
00650 void
00651 c_plscmap1la( PLINT itype, PLINT npts, const PLFLT *pos,
00652 const PLFLT *coord1, const PLFLT *coord2, const PLFLT *coord3, const PLFLT *a, const PLINT *rev )
00653 {
00654 int n;
00655 PLFLT h, l, s, r, g, b;
00656
00657 if ( npts < 2 )
00658 {
00659 plabort( "plscmap1la: Must specify at least two control points" );
00660 return;
00661 }
00662
00663 if ( ( pos[0] != 0 ) || ( pos[npts - 1] != 1 ) )
00664 {
00665 plabort( "plscmap1la: First, last control points must lie on boundary" );
00666 return;
00667 }
00668
00669 if ( npts > PL_MAX_CMAP1CP )
00670 {
00671 plabort( "plscmap1la: exceeded maximum number of control points" );
00672 return;
00673 }
00674
00675
00676
00677 if ( plsc->cmap1 == NULL )
00678 plscmap1n( 0 );
00679
00680
00681
00682 plsc->ncp1 = npts;
00683
00684 for ( n = 0; n < npts; n++ )
00685 {
00686 if ( itype == 0 )
00687 {
00688 h = coord1[n];
00689 l = coord2[n];
00690 s = coord3[n];
00691 }
00692 else
00693 {
00694 r = coord1[n];
00695 g = coord2[n];
00696 b = coord3[n];
00697 c_plrgbhls( r, g, b, &h, &l, &s );
00698 }
00699
00700 plsc->cmap1cp[n].h = h;
00701 plsc->cmap1cp[n].l = l;
00702 plsc->cmap1cp[n].s = s;
00703 plsc->cmap1cp[n].p = pos[n];
00704 plsc->cmap1cp[n].a = a[n];
00705
00706 if ( rev == NULL )
00707 plsc->cmap1cp[n].rev = 0;
00708 else
00709 plsc->cmap1cp[n].rev = rev[n];
00710 }
00711
00712
00713
00714 plcmap1_calc();
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724 void
00725 plcmap1_calc( void )
00726 {
00727 int i, n;
00728 PLFLT delta, dp, dh, dl, ds, da;
00729 PLFLT h, l, s, p, r, g, b, a;
00730
00731
00732
00733 for ( n = 0; n < plsc->ncp1 - 1; n++ )
00734 {
00735 if ( plsc->cmap1cp[n].p == plsc->cmap1cp[n + 1].p )
00736 continue;
00737
00738
00739
00740 dp = plsc->cmap1cp[n + 1].p - plsc->cmap1cp[n].p;
00741 dh = plsc->cmap1cp[n + 1].h - plsc->cmap1cp[n].h;
00742 dl = plsc->cmap1cp[n + 1].l - plsc->cmap1cp[n].l;
00743 ds = plsc->cmap1cp[n + 1].s - plsc->cmap1cp[n].s;
00744 da = plsc->cmap1cp[n + 1].a - plsc->cmap1cp[n].a;
00745
00746
00747
00748 if ( plsc->cmap1cp[n].rev )
00749 dh = ( dh > 0 ) ? dh - 360 : dh + 360;
00750
00751
00752
00753
00754 for ( i = 0; i < plsc->ncol1; i++ )
00755 {
00756 p = (double) i / ( plsc->ncol1 - 1.0 );
00757 if ( ( p < plsc->cmap1cp[n].p ) ||
00758 ( p > plsc->cmap1cp[n + 1].p ) )
00759 continue;
00760
00761
00762
00763 delta = ( p - plsc->cmap1cp[n].p ) / dp;
00764
00765
00766
00767 h = plsc->cmap1cp[n].h + dh * delta;
00768 l = plsc->cmap1cp[n].l + dl * delta;
00769 s = plsc->cmap1cp[n].s + ds * delta;
00770 a = plsc->cmap1cp[n].a + da * delta;
00771
00772 while ( h >= 360. )
00773 h -= 360.;
00774
00775 while ( h < 0. )
00776 h += 360.;
00777
00778 c_plhlsrgb( h, l, s, &r, &g, &b );
00779
00780 plsc->cmap1[i].r = MAX( 0, MIN( 255, (int) ( 256. * r ) ) );
00781 plsc->cmap1[i].g = MAX( 0, MIN( 255, (int) ( 256. * g ) ) );
00782 plsc->cmap1[i].b = MAX( 0, MIN( 255, (int) ( 256. * b ) ) );
00783 plsc->cmap1[i].a = a;
00784 }
00785 }
00786
00787 if ( plsc->level > 0 )
00788 plP_state( PLSTATE_CMAP1 );
00789 }
00790
00791
00803
00804
00805 void
00806 c_plscmap1_range( PLFLT min_color, PLFLT max_color )
00807 {
00808 if ( min_color > max_color || max_color < 0.0 || min_color > 1.0 )
00809 {
00810 plwarn( "plscmap1_range called with invalid color range" );
00811 return;
00812 }
00813 if ( min_color < 0.0 )
00814 {
00815 plwarn( "plscmap1_range called with a negative minimum color value" );
00816 min_color = 0.0;
00817 }
00818 if ( max_color > 1.0 )
00819 {
00820 plwarn( "plscmap1_range called with an out of range maximum color value" );
00821 max_color = 1.0;
00822 }
00823 plsc->cmap1_min = min_color;
00824 plsc->cmap1_max = max_color;
00825 }
00826
00827
00832
00833
00834 void
00835 c_plgcmap1_range( PLFLT *min_color, PLFLT *max_color )
00836 {
00837 *min_color = plsc->cmap1_min;
00838 *max_color = plsc->cmap1_max;
00839 }
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851 void
00852 c_plscmap0n( PLINT ncol0 )
00853 {
00854 int ncol, size, imin, imax;
00855
00856
00857
00858 if ( ncol0 > 0 && plsc->ncol0 == ncol0 )
00859 return;
00860
00861
00862
00863 if ( plsc->ncol0 <= 0 && ncol0 <= 0 )
00864 ncol = 16;
00865 else if ( ncol0 <= 0 )
00866 ncol = plsc->ncol0;
00867 else
00868 ncol = ncol0;
00869
00870 imax = ncol - 1;
00871 size = ncol * sizeof ( PLColor );
00872
00873
00874
00875 if ( plsc->cmap0 == NULL )
00876 {
00877 if ( ( plsc->cmap0 = (PLColor *) calloc( 1, size ) ) == NULL )
00878 {
00879 plexit( "c_plscmap0n: Insufficient memory" );
00880 }
00881 imin = 0;
00882 }
00883 else
00884 {
00885 if ( ( plsc->cmap0 = (PLColor *) realloc( plsc->cmap0, size ) ) == NULL )
00886 {
00887 plexit( "c_plscmap0n: Insufficient memory" );
00888 }
00889 imin = plsc->ncol0;
00890 }
00891
00892
00893
00894 plsc->ncol0 = ncol;
00895 plcmap0_def( imin, imax );
00896
00897 if ( plsc->level > 0 )
00898 plP_state( PLSTATE_CMAP0 );
00899 }
00900
00901
00902
00903
00904
00905
00906
00907 void
00908 color_set( PLINT i, U_CHAR r, U_CHAR g, U_CHAR b, PLFLT a, char *name )
00909 {
00910 plsc->cmap0[i].r = r;
00911 plsc->cmap0[i].g = g;
00912 plsc->cmap0[i].b = b;
00913 plsc->cmap0[i].a = a;
00914 plsc->cmap0[i].name = name;
00915 }
00916
00917 #define color_def( i, r, g, b, a, n ) \
00918 if ( i >= imin && i <= imax ) color_set( i, r, g, b, a, n );
00919
00920
00921
00922
00923
00924
00925
00926
00927 void
00928 plcmap0_def( int imin, int imax )
00929 {
00930 int i, *r, *g, *b;
00931 double *a;
00932 int number_colors;
00933 if ( imin <= imax )
00934 {
00935 cmap0_palette_read( "", &number_colors, &r, &g, &b, &a );
00936 for ( i = imin; i <= MIN( ( number_colors - 1 ), imax ); i++ )
00937 color_def( i, r[i], g[i], b[i], a[i],
00938 "colors defined by default cmap0 palette file" );
00939 free( r );
00940 free( g );
00941 free( b );
00942 free( a );
00943 }
00944 else
00945 {
00946 number_colors = 0;
00947 }
00948
00949
00950
00951 for ( i = MAX( number_colors, imin ); i <= imax; i++ )
00952 color_def( i, 255, 0, 0, 1.0,
00953 "opaque red colour to mark not defined by palette file" );
00954 }
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 void
00967 c_plscmap1n( PLINT ncol1 )
00968 {
00969 int ncol, size;
00970
00971
00972
00973 if ( ncol1 > 0 && plsc->ncol1 == ncol1 )
00974 return;
00975
00976
00977
00978 if ( plsc->ncol1 <= 0 && ncol1 <= 0 )
00979 ncol = 128;
00980 else if ( ncol1 <= 0 )
00981 ncol = plsc->ncol1;
00982 else
00983 ncol = ncol1;
00984
00985 size = ncol * sizeof ( PLColor );
00986
00987
00988
00989 if ( plsc->ncol1 > 0 )
00990 {
00991 if ( ( plsc->cmap1 = (PLColor *) realloc( plsc->cmap1, size ) ) == NULL )
00992 {
00993 plexit( "c_plscmap1n: Insufficient memory" );
00994 }
00995 }
00996 else
00997 {
00998 if ( ( plsc->cmap1 = (PLColor *) calloc( ncol, sizeof ( PLColor ) ) ) == NULL )
00999 {
01000 plexit( "c_plscmap1n: Insufficient memory" );
01001 }
01002 }
01003
01004
01005
01006 plsc->ncol1 = ncol;
01007 if ( plsc->ncp1 == 0 )
01008 plcmap1_def();
01009 else
01010 plcmap1_calc();
01011 }
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026 void
01027 plcmap1_def( void )
01028 {
01029 PLFLT i[6], h[6], l[6], s[6], midpt = 0., vertex = 0.;
01030
01031
01032
01033 i[0] = 0;
01034 i[1] = 0.44;
01035 i[2] = 0.50;
01036 i[3] = 0.50;
01037 i[4] = 0.56;
01038 i[5] = 1;
01039
01040
01041
01042
01043 if ( plsc->cmap0 != NULL )
01044 vertex = ( (PLFLT) plsc->cmap0[0].r +
01045 (PLFLT) plsc->cmap0[0].g +
01046 (PLFLT) plsc->cmap0[0].b ) / 3. / 255.;
01047
01048 if ( vertex < 0.5 )
01049 {
01050 vertex = 0.01;
01051 midpt = 0.10;
01052 }
01053 else
01054 {
01055 vertex = 0.99;
01056 midpt = 0.90;
01057 }
01058
01059
01060
01061 h[0] = 260;
01062 h[1] = 260;
01063 h[2] = 260;
01064 h[3] = 0;
01065 h[4] = 0;
01066 h[5] = 0;
01067
01068
01069
01070 l[0] = 0.5;
01071 l[1] = midpt;
01072 l[2] = vertex;
01073 l[3] = vertex;
01074 l[4] = midpt;
01075 l[5] = 0.5;
01076
01077
01078
01079 s[0] = 1;
01080 s[1] = 1;
01081 s[2] = 1;
01082 s[3] = 1;
01083 s[4] = 1;
01084 s[5] = 1;
01085
01086 c_plscmap1l( 0, 6, i, h, l, s, NULL );
01087
01088 if ( plsc->level > 0 )
01089 plP_state( PLSTATE_CMAP1 );
01090 }
01091
01092
01093
01094
01095
01096
01097
01098 void
01099 c_plscolor( PLINT color )
01100 {
01101 plsc->colorset = 1;
01102 plsc->color = color;
01103 }
01104
01105
01106
01107
01108
01109
01110
01111 PLFLT
01112 value( double n1, double n2, double hue )
01113 {
01114 PLFLT val;
01115
01116 while ( hue >= 360. )
01117 hue -= 360.;
01118 while ( hue < 0. )
01119 hue += 360.;
01120
01121 if ( hue < 60. )
01122 val = n1 + ( n2 - n1 ) * hue / 60.;
01123 else if ( hue < 180. )
01124 val = n2;
01125 else if ( hue < 240. )
01126 val = n1 + ( n2 - n1 ) * ( 240. - hue ) / 60.;
01127 else
01128 val = n1;
01129
01130 return ( val );
01131 }
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147 void
01148 c_plhlsrgb( PLFLT h, PLFLT l, PLFLT s, PLFLT *p_r, PLFLT *p_g, PLFLT *p_b )
01149 {
01150 PLFLT m1, m2;
01151
01152 if ( l <= .5 )
01153 m2 = l * ( s + 1. );
01154 else
01155 m2 = l + s - l * s;
01156
01157 m1 = 2 * l - m2;
01158
01159 *p_r = value( m1, m2, h + 120. );
01160 *p_g = value( m1, m2, h );
01161 *p_b = value( m1, m2, h - 120. );
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175 void
01176 c_plrgbhls( PLFLT r, PLFLT g, PLFLT b, PLFLT *p_h, PLFLT *p_l, PLFLT *p_s )
01177 {
01178 PLFLT h, l, s, d, rc, gc, bc, rgb_min, rgb_max;
01179
01180 rgb_min = MIN( r, MIN( g, b ) );
01181 rgb_max = MAX( r, MAX( g, b ) );
01182
01183 l = ( rgb_min + rgb_max ) / 2.0;
01184
01185 if ( rgb_min == rgb_max )
01186 {
01187 s = 0;
01188 h = 0;
01189 }
01190 else
01191 {
01192 d = rgb_max - rgb_min;
01193 if ( l < 0.5 )
01194 s = 0.5 * d / l;
01195 else
01196 s = 0.5 * d / ( 1. - l );
01197
01198 rc = ( rgb_max - r ) / d;
01199 gc = ( rgb_max - g ) / d;
01200 bc = ( rgb_max - b ) / d;
01201
01202 if ( r == rgb_max )
01203 h = bc - gc;
01204 else if ( g == rgb_max )
01205 h = rc - bc + 2;
01206 else
01207 h = gc - rc - 2;
01208
01209 h = h * 60;
01210 if ( h < 0 )
01211 h = h + 360;
01212 else if ( h >= 360 )
01213 h = h - 360;
01214 }
01215 *p_h = h;
01216 *p_l = l;
01217 *p_s = s;
01218 }
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228 static char *
01229 read_line( char *buffer, int length, FILE *fp )
01230 {
01231 char *pchr;
01232
01233
01234 if ( fgets( buffer, length, fp ) == NULL )
01235 {
01236 return NULL;
01237 }
01238
01239
01240
01241 pchr = strchr( buffer, '\n' );
01242 if ( pchr != NULL )
01243 {
01244 *pchr = '\0';
01245 }
01246 else
01247 {
01248 if ( fscanf( fp, "%*[^\n]\n" ) == EOF && ferror( fp ) )
01249 {
01250 return NULL;
01251 }
01252 }
01253
01254
01255 pchr = strchr( buffer, '\r' );
01256 if ( pchr != NULL )
01257 {
01258 *pchr = '\0';
01259 }
01260
01261
01262 pchr = buffer + strlen( buffer ) - 1;
01263 while ( pchr != buffer && *pchr == ' ' )
01264 {
01265 *pchr = '\0';
01266 pchr--;
01267 }
01268
01269 return buffer;
01270 }
01271
01272
01273
01274
01275
01276
01277
01278
01279 void
01280 cmap0_palette_read( const char *filename,
01281 int *number_colors, int **r, int **g, int **b, double **a )
01282 {
01283 int i, err = 0;
01284 char color_info[COLLEN];
01285 char msgbuf[MSGLEN];
01286 FILE *fp;
01287 char * save_locale = plsave_set_locale();
01288
01289 if ( strlen( filename ) == 0 )
01290 {
01291 fp = plLibOpen( PL_DEFAULT_CMAP0_FILE );
01292 if ( fp == NULL )
01293 {
01294 snprintf( msgbuf, MSGLEN, "Unable to open cmap0 file %s\n", PL_DEFAULT_CMAP0_FILE );
01295 plwarn( msgbuf );
01296 err = 1;
01297 }
01298 }
01299 else
01300 {
01301 fp = plLibOpen( filename );
01302 if ( fp == NULL )
01303 {
01304 snprintf( msgbuf, MSGLEN, "Unable to open cmap0 file %s\n", filename );
01305 plwarn( msgbuf );
01306 err = 1;
01307 }
01308 }
01309 if ( !err && ( fscanf( fp, "%d\n", number_colors ) != 1 || *number_colors < 1 ) )
01310 {
01311 fclose( fp );
01312 snprintf( msgbuf, MSGLEN, "Unrecognized cmap0 header\n" );
01313 plwarn( msgbuf );
01314 err = 1;
01315 }
01316
01317 if ( !err )
01318 {
01319
01320
01321 if ( ( ( *r = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01322 ( ( *g = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01323 ( ( *b = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01324 ( ( *a = (double *) malloc( *number_colors * sizeof ( double ) ) ) == NULL ) )
01325 {
01326 fclose( fp );
01327 plexit( "cmap0_palette_read: insufficient memory" );
01328 }
01329
01330 for ( i = 0; i < *number_colors; i++ )
01331 {
01332 if ( read_line( color_info, COLLEN, fp ) == NULL )
01333 {
01334 err = 1;
01335 break;
01336 }
01337
01338
01339 if ( strlen( color_info ) == 7 )
01340 {
01341 if ( sscanf( color_info, "#%2x%2x%2x",
01342 (int *) ( *r + i ), (int *) ( *g + i ), (int *) ( *b + i ) ) != 3 )
01343 {
01344 err = 1;
01345 break;
01346 }
01347 *( *a + i ) = 1.0;
01348 }
01349 else if ( strlen( color_info ) > 9 )
01350 {
01351 if ( sscanf( color_info, "#%2x%2x%2x %lf",
01352 (int *) ( *r + i ), (int *) ( *g + i ), (int *) ( *b + i ),
01353 (double *) ( *a + i ) ) != 4 )
01354 {
01355 err = 1;
01356 break;
01357 }
01358
01359 if ( *( *a + i ) < -FUZZ_EPSILON || *( *a + i ) > ( 1. + FUZZ_EPSILON ) )
01360 {
01361 err = 1;
01362 break;
01363 }
01364 else if ( *( *a + i ) < 0. )
01365 {
01366 *( *a + i ) = 0.;
01367 }
01368 else if ( *( *a + i ) > 1. )
01369 {
01370 *( *a + i ) = 1.;
01371 }
01372 }
01373 else
01374 {
01375 err = 1;
01376 break;
01377 }
01378 }
01379 fclose( fp );
01380 if ( err )
01381 {
01382 snprintf( msgbuf, MSGLEN, "Unrecognized cmap0 format data line. Line is %s\n",
01383 color_info );
01384 plwarn( msgbuf );
01385 free( *r );
01386 free( *g );
01387 free( *b );
01388 free( *a );
01389 }
01390 }
01391
01392
01393 if ( err )
01394 {
01395 *number_colors = 16;
01396 if ( ( ( *r = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01397 ( ( *g = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01398 ( ( *b = (int *) malloc( *number_colors * sizeof ( int ) ) ) == NULL ) ||
01399 ( ( *a = (double *) malloc( *number_colors * sizeof ( double ) ) ) == NULL ) )
01400 {
01401 plexit( "cmap0_palette_read: insufficient memory" );
01402 }
01403 **r = 255;
01404 **g = 255;
01405 **b = 255;
01406 **a = 1.;
01407 for ( i = 1; i < *number_colors; i++ )
01408 {
01409 *( *r + i ) = 255;
01410 *( *g + i ) = 0;
01411 *( *b + i ) = 0;
01412 *( *a + i ) = 1.0;
01413 }
01414 }
01415
01416 plrestore_locale( save_locale );
01417 }
01418
01419
01420
01421
01422
01423
01424
01425
01426 void
01427 c_plspal0( const char *filename )
01428 {
01429 int i, *r, *g, *b;
01430 double *a;
01431 int number_colors;
01432 cmap0_palette_read( filename, &number_colors, &r, &g, &b, &a );
01433
01434
01435 plscmap0n( 0 );
01436
01437 if ( number_colors > plsc->ncol0 )
01438 {
01439 plscmap0n( number_colors );
01440 }
01441 for ( i = 0; i < number_colors; i++ )
01442 {
01443 c_plscol0a( i, r[i], g[i], b[i], a[i] );
01444 }
01445 free( r );
01446 free( g );
01447 free( b );
01448 free( a );
01449 }
01450
01451
01452
01453
01454
01455 #define fuzzy_range_check( value, min, max, fuzz, err_number ) \
01456 if ( value < ( min - fuzz ) || value > ( max + fuzz ) ) { \
01457 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format data line. Error number is %d. Line is %s\n", err_number, color_info ); \
01458 plwarn( msgbuf ); \
01459 err = 1; \
01460 break; \
01461 } else if ( value < min ) { \
01462 value = min; \
01463 } else if ( value > max ) { \
01464 value = max; \
01465 }
01466
01467
01468
01469
01470
01471
01472
01473 void
01474 c_plspal1( const char *filename, PLBOOL interpolate )
01475 {
01476 int i;
01477 int number_colors;
01478 int format_version, err;
01479 PLBOOL rgb;
01480 char color_info[PALLEN];
01481 int r_i, g_i, b_i, pos_i, rev_i;
01482 double r_d, g_d, b_d, a_d, pos_d;
01483 PLFLT *r, *g, *b, *a, *pos;
01484 PLINT *ri, *gi, *bi;
01485 PLBOOL *rev;
01486 FILE *fp;
01487 char msgbuf[MSGLEN];
01488 char * save_locale = plsave_set_locale();
01489
01490 rgb = TRUE;
01491 err = 0;
01492 format_version = 0;
01493 if ( strlen( filename ) == 0 )
01494 {
01495 fp = plLibOpen( PL_DEFAULT_CMAP1_FILE );
01496 if ( fp == NULL )
01497 {
01498 snprintf( msgbuf, MSGLEN, "Unable to open cmap1 .pal file %s\n", PL_DEFAULT_CMAP1_FILE );
01499 plwarn( msgbuf );
01500 goto finish;
01501 }
01502 }
01503 else
01504 {
01505 fp = plLibOpen( filename );
01506 if ( fp == NULL )
01507 {
01508 snprintf( msgbuf, MSGLEN, "Unable to open cmap1 .pal file %s\n", filename );
01509 plwarn( msgbuf );
01510 goto finish;
01511 }
01512 }
01513
01514 if ( read_line( color_info, PALLEN, fp ) == NULL )
01515 {
01516 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
01517 plwarn( msgbuf );
01518 fclose( fp );
01519 goto finish;
01520 }
01521 if ( strncmp( color_info, "v2 ", 2 ) == 0 )
01522 {
01523 format_version = 1;
01524 if ( strncmp( &color_info[3], "hls", 3 ) == 0 )
01525 rgb = FALSE;
01526 else if ( strncmp( &color_info[3], "rgb", 3 ) == 0 )
01527 rgb = TRUE;
01528 else
01529 {
01530 snprintf( msgbuf, MSGLEN, "Invalid color space %s - assuming RGB\n", &color_info[3] );
01531 plwarn( msgbuf );
01532 rgb = TRUE;
01533 }
01534 if ( read_line( color_info, PALLEN, fp ) == NULL )
01535 {
01536 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
01537 plwarn( msgbuf );
01538 fclose( fp );
01539 goto finish;
01540 }
01541 }
01542
01543 if ( sscanf( color_info, "%d\n", &number_colors ) != 1 || number_colors < 2 )
01544 {
01545 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of colors) %s\n", color_info );
01546 plwarn( msgbuf );
01547 fclose( fp );
01548 goto finish;
01549 }
01550
01551 r = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01552 g = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01553 b = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01554 ri = (PLINT *) malloc( number_colors * sizeof ( PLINT ) );
01555 gi = (PLINT *) malloc( number_colors * sizeof ( PLINT ) );
01556 bi = (PLINT *) malloc( number_colors * sizeof ( PLINT ) );
01557 a = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01558 pos = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01559 rev = (PLBOOL *) malloc( number_colors * sizeof ( PLBOOL ) );
01560
01561 if ( format_version == 0 )
01562 {
01563 int return_sscanf, return_sscanf_old = 0;
01564
01565 for ( i = 0; i < number_colors; i++ )
01566 {
01567 if ( read_line( color_info, PALLEN, fp ) == NULL )
01568 {
01569 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
01570 plwarn( msgbuf );
01571 fclose( fp );
01572 goto finish;
01573 }
01574
01575 color_info[PALLEN - 1] = '\0';
01576 return_sscanf = sscanf( color_info, "#%2x%2x%2x %d %d", &r_i, &g_i, &b_i, &pos_i, &rev_i );
01577 if ( return_sscanf < 4 || ( return_sscanf_old != 0 && return_sscanf != return_sscanf_old ) )
01578 {
01579 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of items for version 1 of format) %s\n", color_info );
01580 plwarn( msgbuf );
01581 err = 1;
01582 break;
01583 }
01584 return_sscanf_old = return_sscanf;
01585
01586
01587 r[i] = (PLFLT) r_i / 255.;
01588 g[i] = (PLFLT) g_i / 255.;
01589 b[i] = (PLFLT) b_i / 255.;
01590 a[i] = 1.0;
01591 pos[i] = 0.01 * (PLFLT) pos_i;
01592 fuzzy_range_check( r[i], 0., 1., FUZZ_EPSILON, 1 );
01593 fuzzy_range_check( g[i], 0., 1., FUZZ_EPSILON, 2 );
01594 fuzzy_range_check( b[i], 0., 1., FUZZ_EPSILON, 3 );
01595 fuzzy_range_check( pos[i], 0., 1., FUZZ_EPSILON, 4 );
01596 if ( return_sscanf == 5 )
01597 {
01598
01599 rev[i] = (PLBOOL) rev_i;
01600 }
01601 }
01602 if ( return_sscanf == 4 )
01603 {
01604
01605 free( rev );
01606 rev = NULL;
01607 }
01608 }
01609 else
01610 {
01611
01612 for ( i = 0; i < number_colors; i++ )
01613 {
01614 if ( read_line( color_info, PALLEN, fp ) == NULL )
01615 {
01616 snprintf( msgbuf, MSGLEN, "Error reading cmap1 .pal file %s\n", filename );
01617 plwarn( msgbuf );
01618 fclose( fp );
01619 goto finish;
01620 }
01621 if ( sscanf( color_info, "%lf %lf %lf %lf %lf %d", &pos_d, &r_d, &g_d, &b_d, &a_d, &rev_i ) != 6 )
01622 {
01623 snprintf( msgbuf, MSGLEN, "Unrecognized cmap1 format (wrong number of items for version 2 of format) %s\n", color_info );
01624 plwarn( msgbuf );
01625 err = 1;
01626 break;
01627 }
01628
01629 r[i] = (PLFLT) r_d;
01630 g[i] = (PLFLT) g_d;
01631 b[i] = (PLFLT) b_d;
01632 a[i] = (PLFLT) a_d;
01633 pos[i] = (PLFLT) pos_d;
01634
01635
01636
01637 if ( rgb )
01638 {
01639 fuzzy_range_check( r[i], 0., 1., FUZZ_EPSILON, 5 );
01640 }
01641 else
01642 {
01643 fuzzy_range_check( r[i], 0., 360., ( 360. * FUZZ_EPSILON ), 6 );
01644 }
01645 fuzzy_range_check( g[i], 0., 1., FUZZ_EPSILON, 7 );
01646 fuzzy_range_check( b[i], 0., 1., FUZZ_EPSILON, 8 );
01647 fuzzy_range_check( a[i], 0., 1., FUZZ_EPSILON, 9 );
01648 fuzzy_range_check( pos[i], 0., 1., FUZZ_EPSILON, 10 );
01649
01650 rev[i] = (PLBOOL) rev_i;
01651 }
01652 }
01653 fclose( fp );
01654
01655 if ( !err )
01656 {
01657 if ( interpolate )
01658 {
01659 c_plscmap1la( rgb, number_colors, pos, r, g, b, a, rev );
01660 }
01661 else
01662 {
01663 for ( i = 0; i < number_colors; i++ )
01664 {
01665 ri[i] = r[i] * 255.0;
01666 gi[i] = g[i] * 255.0;
01667 bi[i] = b[i] * 255.0;
01668 }
01669 c_plscmap1a( ri, gi, bi, a, number_colors );
01670 }
01671 }
01672 else
01673 {
01674
01675
01676 free( r );
01677 free( g );
01678 free( b );
01679 free( pos );
01680 number_colors = 2;
01681 r = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01682 g = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01683 b = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01684 pos = (PLFLT *) malloc( number_colors * sizeof ( PLFLT ) );
01685 r[0] = 0.;
01686 r[1] = 1.;
01687 g[0] = 0.;
01688 g[1] = 0.;
01689 b[0] = 0.;
01690 b[1] = 0.;
01691 pos[0] = 0.;
01692 pos[1] = 1.;
01693 c_plscmap1l( TRUE, number_colors, pos, r, g, b, NULL );
01694 }
01695
01696 free( r );
01697 free( g );
01698 free( b );
01699 free( ri );
01700 free( gi );
01701 free( bi );
01702 free( a );
01703 free( pos );
01704 free( rev );
01705
01706 finish: plrestore_locale( save_locale );
01707 }
01708
01709
01710
01711
01712
01713
01714
01715
01716
01717
01718
01719 void
01720 plwarn( const char *errormsg )
01721 {
01722 int was_gfx = 0;
01723
01724 if ( plsc->graphx == 1 )
01725 {
01726 was_gfx = 1;
01727 pltext();
01728 }
01729
01730 fprintf( stderr, "\n*** PLPLOT WARNING ***\n" );
01731 if ( *errormsg != '\0' )
01732 fprintf( stderr, "%s\n", errormsg );
01733
01734 if ( was_gfx == 1 )
01735 plgra();
01736 }
01737
01738
01739
01740
01741
01742
01743
01744
01745
01746
01747
01748
01749 void
01750 plabort( const char *errormsg )
01751 {
01752 if ( abort_handler != NULL )
01753 ( *abort_handler )( errormsg );
01754
01755 if ( plsc->errcode != NULL )
01756 *( plsc->errcode ) = 1;
01757
01758 if ( plsc->errmsg != NULL )
01759 {
01760 sprintf( plsc->errmsg, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n" );
01761 if ( *errormsg != '\0' )
01762 sprintf( plsc->errmsg, "%s, aborting operation\n", errormsg );
01763 }
01764 else
01765 {
01766 int was_gfx = 0;
01767
01768 if ( plsc->graphx == 1 )
01769 {
01770 was_gfx = 1;
01771 pltext();
01772 }
01773
01774 fprintf( stderr, "\n*** PLPLOT ERROR, ABORTING OPERATION ***\n" );
01775 if ( *errormsg != '\0' )
01776 fprintf( stderr, "%s, aborting operation\n", errormsg );
01777
01778 if ( was_gfx == 1 )
01779 plgra();
01780 }
01781 }
01782
01783
01784
01785
01786
01787
01788
01789
01790 void
01791 plsabort( void ( *handler )( const char * ) )
01792 {
01793 abort_handler = handler;
01794 }
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806
01807
01808 void
01809 plexit( const char *errormsg )
01810 {
01811 int status = 1;
01812
01813 if ( exit_handler != NULL )
01814 status = ( *exit_handler )( errormsg );
01815
01816 plsc->nopause = 1;
01817 if ( *errormsg != '\0' )
01818 {
01819 fprintf( stderr, "\n*** PLPLOT ERROR, IMMEDIATE EXIT ***\n" );
01820 fprintf( stderr, "%s\n", errormsg );
01821 }
01822 plend();
01823
01824 fprintf( stderr, "Program aborted\n" );
01825 exit( status );
01826 }
01827
01828
01829
01830
01831
01832
01833
01834 void
01835 plsexit( int ( *handler )( const char * ) )
01836 {
01837 exit_handler = handler;
01838 }
01839
01840
01841
01842
01843
01844
01845
01846
01847
01848
01849
01850 void
01851 c_plgra( void )
01852 {
01853 if ( plsc->level > 0 )
01854 plP_esc( PLESC_GRAPH, NULL );
01855 }
01856
01857 void
01858 c_plxormod( PLINT mode, PLINT *status )
01859 {
01860 static int ostate = 0;
01861
01862 if ( !plsc->dev_xor )
01863 {
01864 *status = 0;
01865 return;
01866 }
01867
01868 if ( plsc->level > 0 )
01869 {
01870 plP_esc( PLESC_XORMOD, &mode );
01871 if ( mode )
01872 {
01873 ostate = plsc->plbuf_write;
01874 plsc->plbuf_write = 0;
01875 }
01876 else
01877 plsc->plbuf_write = ostate;
01878 }
01879 *status = 1;
01880 }
01881
01882
01887 void
01888 c_plsdrawmode( PLINT mode )
01889 {
01890 if ( !plsc->dev_modeset )
01891 {
01892 plwarn( "plsdrawmode: Mode setting is not supported" );
01893 }
01894 else if ( plsc->level > 0 )
01895 {
01896 plP_esc( PLESC_MODESET, &mode );
01897 }
01898 else
01899 {
01900 plwarn( "plsdrawmode: Initialize PLplot first" );
01901 }
01902 return;
01903 }
01904
01905
01910 PLINT
01911 c_plgdrawmode()
01912 {
01913 PLINT mode;
01914
01915 if ( !plsc->dev_modeset )
01916 {
01917 plwarn( "plgdrawmode: Mode getting is not supported" );
01918 mode = PL_DRAWMODE_UNKNOWN;
01919 }
01920 else if ( plsc->level > 0 )
01921 {
01922 plP_esc( PLESC_MODEGET, &mode );
01923 }
01924 else
01925 {
01926 plwarn( "plsdrawmode: Initialize PLplot first" );
01927 mode = PL_DRAWMODE_UNKNOWN;
01928 }
01929
01930 return ( mode );
01931 }
01932
01933
01934
01935
01936
01937
01938
01939 void
01940 c_pltext( void )
01941 {
01942 if ( plsc->level > 0 )
01943 plP_esc( PLESC_TEXT, NULL );
01944 }
01945
01946
01947
01948
01949
01950
01951
01952
01953
01954 void
01955 pl_cmd( PLINT op, void *ptr )
01956 {
01957 plP_esc( op, ptr );
01958 }
01959
01960
01961
01962
01963
01964
01965
01966
01967
01968
01969
01970
01971
01972
01973
01974
01975
01976
01977 char *
01978 plFindCommand( const char *fn )
01979 {
01980 char *fs = NULL, *dn;
01981
01982
01983 if ( plInBuildTree() == 1 )
01984 {
01985 plGetName( BUILD_DIR, "bindings/tk", fn, &fs );
01986 if ( !plFindName( fs ) )
01987 return fs;
01988 else
01989 {
01990 plGetName( SOURCE_DIR, "scripts", fn, &fs );
01991 if ( !plFindName( fs ) )
01992 return fs;
01993 }
01994 }
01995
01996
01997
01998 #if defined ( PLPLOT_BIN_ENV )
01999 if ( ( dn = getenv( PLPLOT_BIN_ENV ) ) != NULL )
02000 {
02001 plGetName( dn, "", fn, &fs );
02002 if ( !plFindName( fs ) )
02003 return fs;
02004 fprintf( stderr, PLPLOT_BIN_ENV "=\"%s\"\n", dn );
02005 }
02006 #endif // PLPLOT_BIN_ENV
02007
02008
02009
02010 plGetName( ".", "", fn, &fs );
02011 if ( !plFindName( fs ) )
02012 return fs;
02013
02014
02015
02016 #if defined ( PLPLOT_HOME_ENV )
02017 if ( ( dn = getenv( PLPLOT_HOME_ENV ) ) != NULL )
02018 {
02019 plGetName( dn, "bin", fn, &fs );
02020 if ( !plFindName( fs ) )
02021 return fs;
02022 fprintf( stderr, PLPLOT_HOME_ENV "=\"%s\"\n", dn );
02023 }
02024 #endif // PLPLOT_HOME_ENV
02025
02026
02027
02028 #if defined ( BIN_DIR )
02029 plGetName( BIN_DIR, "", fn, &fs );
02030 if ( !plFindName( fs ) )
02031 return fs;
02032 #endif
02033
02034
02035
02036 free_mem( fs );
02037 fprintf( stderr, "plFindCommand: cannot locate command: %s\n", fn );
02038 #if defined ( BIN_DIR )
02039 fprintf( stderr, "bin dir=\"" BIN_DIR "\"\n" );
02040 #endif // BIN_DIR
02041 return NULL;
02042 }
02043
02044
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056 FILE *
02057 plLibOpen( const char *fn )
02058 {
02059 FILE *ret = NULL;
02060
02061 PDFstrm *pdfs = plLibOpenPdfstrm( fn );
02062 if ( pdfs == NULL )
02063 {
02064 return NULL;
02065 }
02066 if ( pdfs->file != NULL )
02067 {
02068 ret = pdfs->file;
02069 pdfs->file = NULL;
02070 }
02071 pdf_close( pdfs );
02072 return ret;
02073 }
02074
02075 PDFstrm *
02076 plLibOpenPdfstrm( const char *fn )
02077 {
02078 PDFstrm *file;
02079 char *fs = NULL, *dn = NULL;
02080
02081
02082
02083 if ( plInBuildTree() == 1 )
02084 {
02085 plGetName( SOURCE_DIR, "data", fn, &fs );
02086
02087 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02088 goto done;
02089 }
02090
02091
02092
02093 #if defined ( PLPLOT_LIB_ENV )
02094 if ( ( dn = getenv( PLPLOT_LIB_ENV ) ) != NULL )
02095 {
02096 plGetName( dn, "", fn, &fs );
02097
02098 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02099 goto done;
02100 fprintf( stderr, PLPLOT_LIB_ENV "=\"%s\"\n", dn );
02101 }
02102 #endif // PLPLOT_LIB_ENV
02103
02104
02105
02106 if ( ( file = pdf_fopen( fn, "rb" ) ) != NULL )
02107 {
02108 pldebug( "plLibOpenPdfstr", "Found file %s in current directory.\n", fn );
02109 free_mem( fs );
02110 return ( file );
02111 }
02112
02113
02114
02115 #if defined ( PLPLOT_HOME_ENV )
02116 if ( ( dn = getenv( PLPLOT_HOME_ENV ) ) != NULL )
02117 {
02118 plGetName( dn, "lib", fn, &fs );
02119
02120 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02121 goto done;
02122 fprintf( stderr, PLPLOT_HOME_ENV "=\"%s\"\n", dn );
02123 }
02124 #endif // PLPLOT_HOME_ENV/lib
02125
02126
02127
02128 #if defined ( DATA_DIR )
02129 plGetName( DATA_DIR, "", fn, &fs );
02130
02131 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02132 goto done;
02133 #endif // DATA_DIR
02134
02135
02136
02137 #ifdef PLLIBDEV
02138 plGetName( PLLIBDEV, "", fn, &fs );
02139
02140 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02141 goto done;
02142 #endif // PLLIBDEV
02143
02144 #ifdef macintosh
02145 file = plMacLibOpen( fn );
02146 if ( file != NULL )
02147 goto done;
02148 #endif // macintosh
02149
02150 if ( plplotLibDir != NULL )
02151 {
02152 plGetName( plplotLibDir, "", fn, &fs );
02153 if ( ( file = pdf_fopen( fs, "rb" ) ) != NULL )
02154 goto done;
02155 }
02156
02157
02158 pldebug( "plLibOpenPdfstr", "File %s not found.\n", fn );
02159 free_mem( fs );
02160 return NULL;
02161
02162 done:
02163 pldebug( "plLibOpenPdfstr", "Found file %s\n", fs );
02164 free_mem( fs );
02165 return ( file );
02166 }
02167
02168
02169
02170
02171
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186 #ifdef __unix
02187 int
02188 plFindName( char *p )
02189 {
02190 int n;
02191 char buf[PLPLOT_MAX_PATH], *cp;
02192 extern int errno;
02193 struct stat sbuf;
02194
02195 pldebug( "plFindName", "Trying to find %s\n", p );
02196 while ( ( n = readlink( p, buf, PLPLOT_MAX_PATH ) ) > 0 )
02197 {
02198 pldebug( "plFindName", "Readlink read %d chars at: %s\n", n, p );
02199 if ( buf[0] == '/' )
02200 {
02201
02202
02203 strncpy( p, buf, n );
02204 p[n] = '\0';
02205 pldebug( "plFindName", "Link is absolute: %s\n", p );
02206 }
02207 else
02208 {
02209
02210
02211 cp = 1 + strrchr( p, '/' );
02212 strncpy( cp, buf, n );
02213 cp[n] = '\0';
02214 pldebug( "plFindName",
02215 "Link is relative: %s\n\tTotal path:%s\n", cp, p );
02216 }
02217 }
02218
02219
02220
02221 #ifdef SX
02222 #define S_ISREG( mode ) ( mode & S_IFREG )
02223 #endif
02224
02225
02226
02227 if ( errno == EINVAL || errno == ENXIO )
02228 {
02229 pldebug( "plFindName", "%s may be the one...\n", p );
02230 if ( ( stat( p, &sbuf ) == 0 ) && S_ISREG( sbuf.st_mode ) )
02231 {
02232 pldebug( "plFindName", "%s is a regular file\n", p );
02233 return ( access( p, X_OK ) );
02234 }
02235 }
02236 pldebug( "plFindName", "%s found but is not executable\n", p );
02237 return ( errno ? errno : -1 );
02238 }
02239
02240 #else
02241 int
02242 plFindName( char *p )
02243 {
02244 return 1;
02245 }
02246 #endif
02247
02248
02249
02250
02251
02252
02253
02254
02255
02256
02257 void
02258 plGetName( const char *dir, const char *subdir, const char *filename, char **filespec )
02259 {
02260 int lfilespec;
02261
02262
02263
02264 free_mem( *filespec );
02265 lfilespec = strlen( dir ) + strlen( subdir ) + strlen( filename ) + 10;
02266 if ( ( *filespec = (char *) malloc( lfilespec ) ) == NULL )
02267 {
02268 plexit( "plGetName: Insufficient memory" );
02269 }
02270
02271 strcpy( *filespec, dir );
02272
02273 if ( *subdir != '\0' )
02274 {
02275 strcat_delim( *filespec );
02276 strcat( *filespec, subdir );
02277 }
02278 if ( *filename != '\0' )
02279 {
02280 strcat_delim( *filespec );
02281 strcat( *filespec, filename );
02282 }
02283 pldebug( "plGetName", "Length of full pathname of file to be found is %d\n", lfilespec );
02284 pldebug( "plGetName", "Full pathname of file to be found is %s\n", *filespec );
02285 }
02286
02287
02288
02289
02290
02291
02292
02293
02294 void
02295 strcat_delim( char *dirspec )
02296 {
02297 int ldirspec = strlen( dirspec );
02298 #if defined ( MSDOS ) || defined ( WIN32 )
02299 if ( dirspec[ldirspec - 1] != '\\' )
02300 strcat( dirspec, "\\" );
02301 #elif defined ( macintosh )
02302 if ( dirspec[ldirspec - 1] != ':' )
02303 strcat( dirspec, ":" );
02304 #else // unix is the default
02305 if ( dirspec[ldirspec - 1] != '/' )
02306 strcat( dirspec, "/" );
02307 #endif
02308 }
02309
02310
02311
02312
02313
02314
02315
02316
02317
02318 void
02319 plcol_interp( PLStream *pls, PLColor *newcolor, int i, int ncol )
02320 {
02321 PLFLT x, delta;
02322 int il, ir;
02323
02324 x = (double) ( i * ( pls->ncol1 - 1 ) ) / (double) ( ncol - 1 );
02325 il = (int) x;
02326 ir = il + 1;
02327 delta = x - il;
02328
02329 if ( ir > pls->ncol1 || il < 0 )
02330 fprintf( stderr, "Invalid color\n" );
02331
02332 else if ( ir == pls->ncol1 || ( delta == 0. ) )
02333 {
02334 newcolor->r = pls->cmap1[il].r;
02335 newcolor->g = pls->cmap1[il].g;
02336 newcolor->b = pls->cmap1[il].b;
02337 newcolor->a = pls->cmap1[il].a;
02338 }
02339 else
02340 {
02341 newcolor->r = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].r + delta * pls->cmap1[ir].r );
02342 newcolor->g = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].g + delta * pls->cmap1[ir].g );
02343 newcolor->b = (unsigned char) ( ( 1. - delta ) * pls->cmap1[il].b + delta * pls->cmap1[ir].b );
02344 newcolor->a = ( 1. - delta ) * pls->cmap1[il].a + delta * pls->cmap1[ir].a;
02345 }
02346 }
02347
02348
02349
02350
02351
02352
02353
02354
02355
02356 #define MAX_NUM_TRIES 10
02357 void
02358 plOpenFile( PLStream *pls )
02359 {
02360 int i = 0, count = 0;
02361 size_t len;
02362 char line[BUFFER_SIZE];
02363
02364 while ( pls->OutFile == NULL )
02365 {
02366
02367
02368
02369 if ( pls->family && pls->BaseName != NULL )
02370 plP_getmember( pls );
02371
02372
02373
02374 if ( pls->FileName == NULL )
02375 {
02376 do
02377 {
02378 fprintf( stdout, "Enter graphics output file name: " );
02379 plio_fgets( line, sizeof ( line ), stdin );
02380 len = strlen( line );
02381 if ( len )
02382 len--;
02383 line[len] = '\0';
02384 count++;
02385 } while ( !len && count < MAX_NUM_TRIES );
02386 plP_sfnam( pls, line );
02387 }
02388
02389
02390
02391 if ( !strcmp( pls->FileName, "-" ) )
02392 {
02393 pls->OutFile = stdout;
02394 pls->output_type = 1;
02395 break;
02396 }
02397
02398
02399
02400 if ( pls->family && pls->BaseName != NULL )
02401 plP_getmember( pls );
02402
02403 if ( i++ > 10 )
02404 plexit( "Too many tries." );
02405
02406 if ( ( pls->OutFile = fopen( pls->FileName, "wb+" ) ) == NULL )
02407 fprintf( stderr, "Can't open %s.\n", pls->FileName );
02408 else
02409 pldebug( "plOpenFile", "Opened %s\n", pls->FileName );
02410 }
02411 }
02412
02413
02414
02415
02416
02417
02418
02419 void
02420 plCloseFile( PLStream *pls )
02421 {
02422 if ( pls->OutFile != NULL )
02423 {
02424
02425 if ( pls->FileName && strcmp( pls->FileName, "-" ) == 0 )
02426 return;
02427
02428 fclose( pls->OutFile );
02429 pls->OutFile = NULL;
02430 }
02431 }
02432
02433
02434
02435
02436
02437
02438
02439 void
02440 plP_getmember( PLStream *pls )
02441 {
02442 char tmp[BUFFER_SIZE];
02443 char prefix[BUFFER_SIZE];
02444 char * suffix;
02445 char num[BUFFER_SIZE];
02446 int maxlen;
02447
02448 maxlen = strlen( pls->BaseName ) + 10;
02449 if ( pls->FileName == NULL )
02450 {
02451 if ( ( pls->FileName = (char *) malloc( maxlen ) ) == NULL )
02452 {
02453 plexit( "plP_getmember: Insufficient memory" );
02454 }
02455 }
02456
02457 suffix = strstr( pls->BaseName, "%n" );
02458
02459 snprintf( tmp, BUFFER_SIZE, "%%0%1ii", (int) pls->fflen );
02460 snprintf( num, BUFFER_SIZE, tmp, pls->member );
02461
02462 if ( suffix == NULL )
02463 snprintf( pls->FileName, maxlen, "%s.%s", pls->BaseName, num );
02464 else
02465 {
02466 strncpy( prefix, pls->BaseName, BUFFER_SIZE - 1 );
02467 prefix [( suffix - pls->BaseName < BUFFER_SIZE ) ? ( suffix - pls->BaseName ) : BUFFER_SIZE - 1] = '\0';
02468 snprintf( pls->FileName, maxlen, "%s%s%s", prefix, num, suffix + 2 );
02469 }
02470 }
02471
02472
02473
02474
02475
02476
02477
02478
02479 void
02480 plP_sfnam( PLStream *pls, const char *fnam )
02481 {
02482 char prefix[BUFFER_SIZE];
02483 char * suffix;
02484 int maxlen;
02485 pls->OutFile = NULL;
02486
02487 if ( pls->FileName != NULL )
02488 free( (void *) pls->FileName );
02489
02490 maxlen = 10 + strlen( fnam );
02491 if ( ( pls->FileName = (char *) malloc( maxlen ) ) == NULL )
02492 {
02493 plexit( "plP_sfnam: Insufficient memory" );
02494 }
02495
02496 suffix = strstr( fnam, "%n" );
02497
02498 if ( suffix == NULL )
02499 {
02500 strncpy( pls->FileName, fnam, maxlen - 1 );
02501 pls->FileName[maxlen - 1] = '\0';
02502 }
02503 else
02504 {
02505 strncpy( prefix, fnam, BUFFER_SIZE - 1 );
02506 prefix [( suffix - fnam ) < BUFFER_SIZE ? ( suffix - fnam ) : BUFFER_SIZE - 1] = '\0';
02507 snprintf( pls->FileName, maxlen, "%s%s", prefix, suffix + 2 );
02508 }
02509
02510 if ( pls->BaseName != NULL )
02511 free( (void *) pls->BaseName );
02512
02513 if ( ( pls->BaseName = (char *) malloc( maxlen ) ) == NULL )
02514 {
02515 plexit( "plP_sfnam: Insufficient memory" );
02516 }
02517
02518 strncpy( pls->BaseName, fnam, maxlen - 1 );
02519 pls->BaseName[maxlen - 1] = '\0';
02520 }
02521
02522
02523
02524
02525
02526
02527
02528 void
02529 plFamInit( PLStream *pls )
02530 {
02531 if ( pls->family )
02532 {
02533 pls->bytecnt = 0;
02534 if ( !pls->member )
02535 pls->member = 1;
02536 if ( !pls->finc )
02537 pls->finc = 1;
02538 if ( !pls->fflen )
02539 pls->fflen = 1;
02540 if ( !pls->bytemax )
02541 pls->bytemax = PL_FILESIZE_KB * 1000;
02542 }
02543 }
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555 void
02556 plGetFam( PLStream *pls )
02557 {
02558 PLFLT xpmm_loc, ypmm_loc;
02559 if ( pls->family )
02560 {
02561 if ( pls->bytecnt > pls->bytemax || pls->famadv )
02562 {
02563 PLINT local_page_status = pls->page_status;
02564 plP_tidy();
02565 pls->member += pls->finc;
02566 pls->famadv = 0;
02567 plP_init();
02568
02569
02570 pls->page_status = local_page_status;
02571
02572
02573
02574
02575 plP_gpixmm( &xpmm_loc, &ypmm_loc );
02576 plP_setpxl( xpmm_loc * plsc->caspfactor, ypmm_loc / plsc->caspfactor );
02577 return;
02578 }
02579 }
02580 }
02581
02582
02583
02584
02585
02586
02587
02588
02589
02590
02591 void
02592 plRotPhy( PLINT orient, PLINT xmin, PLINT ymin, PLINT xmax, PLINT ymax,
02593 PLINT *px, PLINT *py )
02594 {
02595 int x, y;
02596
02597 x = *px;
02598 y = *py;
02599
02600 switch ( orient % 4 )
02601 {
02602 case 1:
02603 *px = xmin + ( y - ymin );
02604 *py = ymin + ( xmax - x );
02605 break;
02606
02607 case 2:
02608 *px = xmin + ( xmax - x );
02609 *py = ymin + ( ymax - y );
02610 break;
02611
02612 case 3:
02613 *px = xmin + ( ymax - y );
02614 *py = ymin + ( x - xmin );
02615 break;
02616
02617 default:
02618 break;
02619 }
02620 }
02621
02622
02623
02624
02625
02626
02627
02628
02629 PLDev *
02630 plAllocDev( PLStream *pls )
02631 {
02632 if ( pls->dev != NULL )
02633 free( (void *) pls->dev );
02634
02635 pls->dev = calloc( 1, (size_t) sizeof ( PLDev ) );
02636 if ( pls->dev == NULL )
02637 plexit( "plAllocDev: cannot allocate memory\n" );
02638
02639 return (PLDev *) pls->dev;
02640 }
02641
02642
02643
02644
02645
02646
02647
02648 void
02649 plGinInit( PLGraphicsIn *gin )
02650 {
02651 gin->type = 0;
02652 gin->state = 0;
02653 gin->keysym = 0;
02654 gin->button = 0;
02655 gin->string[0] = '\0';
02656 gin->pX = gin->pY = -1;
02657 gin->dX = gin->dY = 0.;
02658 gin->wX = gin->wY = 0.;
02659 }
02660
02661
02662
02663
02664
02665
02666
02667 PLINT
02668 plGetInt( const char *s )
02669 {
02670 int m;
02671 int i = 0;
02672 char line[BUFFER_SIZE];
02673
02674 while ( i++ < 10 )
02675 {
02676 fputs( s, stdout );
02677 plio_fgets( line, sizeof ( line ), stdin );
02678
02679 #ifdef MSDOS
02680 m = atoi( line );
02681 return ( m );
02682 #else
02683 if ( sscanf( line, "%d", &m ) == 1 )
02684 return ( m );
02685 fprintf( stdout, "No value or value out of range; please try again\n" );
02686 #endif
02687 }
02688 plexit( "Too many tries." );
02689 return ( 0 );
02690 }
02691
02692
02693
02694
02695
02696
02697
02698 PLFLT
02699 plGetFlt( const char *s )
02700 {
02701 PLFLT m;
02702 double m1;
02703 int i = 0;
02704 char line[BUFFER_SIZE];
02705
02706 while ( i++ < 10 )
02707 {
02708 fputs( s, stdout );
02709 plio_fgets( line, sizeof ( line ), stdin );
02710
02711 #ifdef MSDOS
02712 m = atof( line );
02713 return ( m );
02714 #else
02715 if ( sscanf( line, "%lf", &m1 ) == 1 )
02716 {
02717 m = (PLFLT) m1;
02718 return ( m );
02719 }
02720 fprintf( stdout, "No value or value out of range; please try again\n" );
02721 #endif
02722 }
02723 plexit( "Too many tries." );
02724 return ( 0. );
02725 }
02726
02727
02728
02729
02730
02731
02732
02733
02734 char PLDLLIMPEXP *
02735 plstrdup( const char *src )
02736 {
02737 char *dest = (char *) malloc( ( strlen( src ) + 1 ) * sizeof ( char ) );
02738 if ( dest != NULL )
02739 strcpy( dest, src );
02740 else
02741 plabort( "Out of memory" );
02742
02743 return dest;
02744 }
02745
02746 #ifndef PL_HAVE_SNPRINTF
02747
02748
02749
02750
02751
02752
02753
02754
02755 int
02756 plsnprintf( char *buffer, int n, const char *format, ... )
02757 {
02758 int ret;
02759
02760 va_list args;
02761 va_start( args, format );
02762 ret = vsprintf( buffer, fmt, args );
02763 va_end( argptr );
02764
02765
02766 if ( ret > n - 1 )
02767 plabort( "plsnprintf: buffer overrun" );
02768
02769 return ret;
02770 }
02771
02772
02773
02774
02775
02776
02777
02778
02779
02780 int
02781 plsnscanf( const char *buffer, int n, const char *format, ... )
02782 {
02783 int ret;
02784
02785 va_list argptr;
02786 va_start( argptr, format );
02787 ret = vsscanf( buffer, fmt, args );
02788 va_end( argptr );
02789
02790 return ret;
02791 }
02792
02793 #endif // PL_HAVE_SNPRINTF
02794
02795
02796
02797
02798
02799
02800
02801 void
02802 c_plseed( unsigned int s )
02803 {
02804 init_genrand( s );
02805 }
02806
02807
02808
02809
02810
02811
02812
02813 PLFLT
02814 c_plrandd( void )
02815 {
02816 return (PLFLT) ( genrand_real1() );
02817 }
02818
02819
02820
02821
02822
02823
02824
02825
02826
02827
02828
02829
02830
02831 char *
02832 plsave_set_locale( void )
02833 {
02834 char * setlocale_ptr;
02835 char * saved_lc_numeric_locale;
02836
02837 if ( !( saved_lc_numeric_locale = (char *) malloc( 100 * sizeof ( char ) ) ) )
02838 {
02839 plexit( "plsave_set_locale: out of memory" );
02840 }
02841
02842
02843 if ( !( setlocale_ptr = setlocale( LC_NUMERIC, NULL ) ) )
02844 {
02845 plexit( "plsave_set_locale: LC_NUMERIC locale could not be determined for NULL locale.\n" );
02846 }
02847 strncpy( saved_lc_numeric_locale, setlocale_ptr, 100 );
02848 saved_lc_numeric_locale[99] = '\0';
02849
02850
02851
02852
02853
02854
02855
02856
02857
02858 if ( !( setlocale( LC_NUMERIC, "C" ) ) )
02859 {
02860 plexit( "plsave_set_locale: LC_NUMERIC locale could not be set to \"C\"" );
02861 }
02862 return saved_lc_numeric_locale;
02863 }
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873 void
02874 plrestore_locale( char *saved_lc_numeric_locale )
02875 {
02876
02877
02878
02879
02880
02881
02882
02883
02884 if ( !( setlocale( LC_NUMERIC, saved_lc_numeric_locale ) ) )
02885 {
02886 char msgbuf[1024];
02887 snprintf( msgbuf, 1024, "plrestore_locale: LC_NUMERIC could not be restored to the default \"%s\" locale.\n", saved_lc_numeric_locale );
02888 plexit( msgbuf );
02889 }
02890 free( saved_lc_numeric_locale );
02891 }
02892