home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / graphics-0.17 / double / double.c next >
Encoding:
C/C++ Source or Header  |  1991-03-11  |  10.8 KB  |  450 lines

  1. /* double - filter for converting, scaling and cutting unformatted (binary) or
  2.    ascii double precision data streams.
  3.  
  4.    Copyright (C) 1989 Free Software Foundation, Inc.
  5.  
  6.    Plot is distributed in the hope that it will be useful, but WITHOUT
  7.    ANY WARRANTY.  No author or distributor accepts responsibility to
  8.    anyone for the consequences of using it or for whether it serves any
  9.    particular purpose or works at all, unless he says so in writing.
  10.    Refer to the GNU General Public License for full details.
  11.  
  12.    Everyone is granted permission to copy, modify and redistribute plot,
  13.    but only under the conditions described in the GNU General Public
  14.    License.  A copy of this license is supposed to have been given to you
  15.    along with plot so you can know your rights and responsibilities.  It
  16.    should be in a file named COPYING.  Among other things, the copyright
  17.    notice and this notice must be preserved on all copies.  */
  18.  
  19. #include <stdio.h>
  20. #include <ctype.h>
  21. #include <math.h>
  22.  
  23. #ifdef STDC_HEADERS
  24. #include <string.h>
  25. #include <stdlib.h>
  26. #else
  27. #ifdef    USG
  28. #include <string.h>
  29. #include <malloc.h>
  30. #else
  31. #include <strings.h>
  32. #include <malloc.h>
  33. #endif    /* USG */
  34. #endif    /* STDC_HEADERS */
  35.  
  36. #include <sys/file.h>
  37.  
  38. char *help_message="\n\
  39. double - a utility for converting, scaling, cutting and pasting unformatted\n\
  40.  (binary) or ascii double precision data.\n\
  41. \n\
  42. Usage:                 double [-option [ARG]] ...<DATA\n\
  43. \n\
  44. Option:         Description:\n\
  45. \n\
  46. add FILE        add values from FILE to each value from DATA.\n\
  47. baseline VALUE  add VALUE to each value from DATA (default 0.0).\n\
  48. bi              read binary (unformatted double precision) values from DATA.\n\
  49. bo              output binary (unformatted double precision) data.\n\
  50. fo              output binary (unformatted single precision) data.\n\
  51. copy NUMBER     output NUMBER values before skipping (default 1).\n\
  52. h               print this help message\n\
  53. join FILE       output one value from FILE for each value from DATA.\n\
  54. mult FILE       multiply values from FILE with each value from DATA.\n\
  55. max             print out the maximum data value.\n\
  56. min             print out the minimum data value.\n\
  57. offset NUMBER   ignore NUMBER values before reading value from DATA.\n\
  58. scale VALUE     scale every output datum by VALUE (default 1.0).\n\
  59. skip NUMBER     skip NUMBER values from DATA after each copying (default 0).\n\
  60. silent            don't output any of the data values.\n\
  61. si              the input contains binary short integers.\n\
  62. sw              reverse the bytes of the short integers on input.\n\
  63. \n\
  64.       Example:\n\
  65.       vector scalar product bvec[i] = 5.0 * avec[i]:\n\
  66.       double -scale 5.0 <avec >bvec\n\
  67. \n\
  68.       vector addition cvec[i] = avec[i] + bvec[i]:\n\
  69.       double -add avec <bvec >cvec\n\
  70. \n\
  71.       vector multiplication cvec[i] = avec[i] * bvec[i]:\n\
  72.       double -mult avec <bvec >cvec\n\
  73.       \n\
  74.       vector editing:\n\
  75.       bvec[i] = avec[2i]\n\
  76.       double -skip 1 <avec >bvec\n\
  77. \n\
  78.       bvec[i] = avec[i+5]\n\
  79.       double -offset 5 <avec >bvec\n\
  80. \n\
  81.       bvec[i] = avec[2i]\n\
  82.       bvec[i+1] = avec[2i+1]\n\
  83.       double -copy 2 -skip 2 <avec >bvec\n\
  84. \n\
  85.       maximum and minimum elements of a vector:\n\
  86.       double -max -silent <avec\n\
  87.       double -min -silent <avec\n\
  88.       rich@rice.edu\n\
  89. \n\
  90. ";
  91.  
  92. int binary_output=0, float_output=0, binary_input=0;
  93. int short_int_input=0, swap_bytes=0;
  94. int take_derivative=0;
  95. #define LARGE (9e30)
  96. double last_data = LARGE;
  97.  
  98. /* readit and writeit return 1 on success and 0 on error */
  99. int
  100. readit (data, fp)
  101.      double *data;
  102.      FILE *fp;
  103. {
  104.   int ret;
  105.   if (binary_input)
  106.     {
  107.       /* returns the number of bytes actually read or 0 for end-of-file */
  108.       ret = read( fileno(fp), (char*)data, sizeof (double));
  109.       return (ret > 0);
  110.     }
  111.   else if (short_int_input)
  112.     {
  113.       /* returns the number of bytes actually read or 0 for end-of-file */
  114.       short int a;
  115.       ret = read( fileno(fp), (char*)&a, sizeof (a));
  116.       if (swap_bytes)
  117.     *data = (short int)((a & 0xFF)<<8 | ((a>>8) & 0xFF));
  118.       else
  119.     *data = a;
  120.       return (ret > 0);
  121.     }
  122.   else
  123.     {
  124.       /* returns EOF on error, zero if succesful */
  125.       ret = fscanf (fp, "%lf", data);
  126.       return (ret > 0);
  127.     }
  128. }
  129.  
  130. int
  131. writeit  (data, fp)
  132.      double *data;
  133.      FILE *fp;
  134. {
  135.   int success = 0;
  136.   if (binary_output)
  137.     {
  138.       /* number of bytes writen is returned.   -1 for error */
  139.       success = (0 < write ( fileno(fp), (char*)data, sizeof (double)));
  140.       return success;
  141.     }
  142.   else if (float_output)
  143.     {
  144.       float tmp;
  145.       tmp = *data;
  146.       /* number of bytes writen is returned.   -1 for error */
  147.       success = (0 < write ( fileno(fp), (char*) &tmp, sizeof (float)));
  148.       return success;
  149.     }
  150.   else
  151.     {
  152. #ifdef V
  153.       /* V system: EOF is returned upon end of input, zero if succesful */
  154.       success = (0 == fprintf (fp, "%.19g\n", *data));
  155. #endif
  156. #ifdef sparc
  157.       /* sparc os4.0: fprintf returns EOF on error, else number
  158.      of characters written */
  159.       int ret = fprintf (fp, "%#.19g\n", *data);
  160.       success = (0 < ret);
  161. #endif
  162. #ifdef myrias
  163.       /* myrias: fprintf returns EOF on error, else number of bytes written. */
  164.       success = (0 < fprintf (fp, "%#.19g\n", *data));
  165. #endif
  166. #ifdef sun3
  167.       /* sun3: fprintf returns EOF on error, zero if succesful */
  168.       success = (0 <= fprintf (fp, "%#.19g\n", *data));
  169. #endif
  170. #ifdef sequent
  171.       /* sequent: fprintf returns EOF on error, zero if succesful */
  172.       success = (0 <= fprintf (fp, "%#.19g\n", *data));
  173. #endif
  174.       /* return zero if write failed. */
  175.       return success;
  176.     }
  177. }
  178.  
  179. int
  180. main (argc, argv)
  181.      int argc;
  182.      char **argv;
  183. {
  184.   int copy=1, offset=0, skip=0;
  185.   char *add_file=0, *mult_file=0, *join_file=0;
  186.   double scale=1., baseline=0.;
  187.   FILE *add_fp = NULL;
  188.   FILE *mult_fp = NULL;
  189.   FILE *join_fp = NULL;
  190.   double data=0., max = -1.0e+38, min=1.0e+38;
  191.   int read_ok=1, write_ok=1, do_min=0, do_max=0, silent=0;
  192.  
  193.   if (argc <= 1)
  194.     {
  195.       printf( "%s", help_message);
  196.       exit (0);
  197.     }
  198.       
  199.   argc--;
  200.   argv++;
  201.   while (argc > 0)
  202.     {
  203.       /*
  204.        *            OPTIONS WHICH ARE SWITCHES (NO ARGUMENT):
  205.        */
  206.       if (!strcmp (*argv, "-bo"))
  207.     /*  output is binary */
  208.     {
  209.       argc--; argv++;
  210.       binary_output = 1;
  211.     }
  212.       else if (!strcmp (*argv, "-fo"))
  213.     /*  output is binary */
  214.     {
  215.       argc--; argv++;
  216.       float_output = 1;
  217.     }
  218.       else if (!strcmp (*argv, "-bi"))
  219.     /*  input is binary */
  220.     {
  221.       argc--; argv++;
  222.       binary_input = 1;
  223.     }
  224.       else if (!strcmp (*argv, "-deriv"))
  225.     /* take the derivative of the input. */
  226.     {
  227.       argc--; argv++;
  228.       take_derivative = 1;
  229.     }
  230.       else if (!strcmp (*argv, "-si"))
  231.     /*  input is binary short ints */
  232.     {
  233.       argc--; argv++;
  234.       short_int_input = 1;
  235.     }
  236.       else if (!strcmp (*argv, "-sw"))
  237.     /*  swap bytes on input */
  238.     {
  239.       argc--; argv++;
  240.       swap_bytes = 1;
  241.     }
  242.       else if (!strcmp (*argv, "-h"))
  243.     {
  244.       printf( "%s", help_message);
  245.       exit (0);
  246.     }
  247.       else if (!strcmp (*argv, "-max"))
  248.     /* output maximum value at the end. */
  249.     {
  250.       do_max = 1;
  251.       argc--; argv++;
  252.     }
  253.       else if (!strcmp (*argv, "-min"))
  254.     /* output minimum value at the end. */
  255.     {
  256.       do_min = 1;
  257.       argc--; argv++;
  258.     }
  259.       else if (!strcmp (*argv, "-silent"))
  260.     /* do not output the data values. */
  261.     {
  262.       silent = 1;
  263.       argc--; argv++;
  264.     }
  265.       /*
  266.        *               OPTIONS WHICH TAKE ARGUMENTS:
  267.        */
  268.       else if (argc < 2)
  269.     {
  270.       fprintf (stderr, "No argument following \"%s\" switch\n", *argv);
  271.       exit (-1);
  272.     }
  273.       else if (!strcmp (*argv, "-add"))
  274.     /*  add values from FILE. */
  275.     {
  276.       argc--; argv++;
  277.       add_file = *argv;
  278.       argc--; argv++;
  279.     }
  280.       else if (!strcmp (*argv, "-baseline"))
  281.     /*  add BASELINE to each output value. */
  282.     {
  283.       argc--; argv++;
  284.       baseline = atof (*argv);
  285.       argc--; argv++;
  286.     }
  287.       else if (!strcmp (*argv, "-copy"))
  288.     /*  number of values to copy to the output each time around. */
  289.     {
  290.       argc--; argv++;
  291.       copy = atoi (*argv);
  292.       argc--; argv++;
  293.     }
  294.       else if (!strcmp (*argv, "-join"))
  295.     /*  merge file. */
  296.     {
  297.       argc--; argv++;
  298.       join_file = *argv;
  299.       argc--; argv++;
  300.     }
  301.       else if (!strcmp (*argv, "-mult"))
  302.     /*  multiply each output value by one value from FILE. */
  303.     {
  304.       argc--; argv++;
  305.       mult_file = *argv;
  306.       argc--; argv++;
  307.     }
  308.       else if (!strcmp (*argv, "-offset"))
  309.     /*  number of data to skip from the beginning of the file. */
  310.     {
  311.       argc--; argv++;
  312.       offset = atoi (*argv);
  313.       argc--; argv++;
  314.     }
  315.       else if (!strcmp (*argv, "-scale"))
  316.     /*  scale each output value by command line value. */
  317.     {
  318.       argc--; argv++;
  319.       scale = atof (*argv);
  320.       argc--; argv++;
  321.     }
  322.       else if (!strcmp (*argv, "-skip"))
  323.     /* number of values to skip between those we copy. */
  324.     {
  325.       argc--; argv++;
  326.       skip = atoi (*argv);
  327.       argc--; argv++;
  328.     }
  329.       else
  330.     {
  331.       fprintf (stderr, "unknown switch \"%s\"\n", *argv);
  332.       argc--; argv++;
  333.     }
  334.     }
  335.   
  336.   /*  open additive file. */
  337.   if (add_file )
  338.     {
  339.       add_fp = fopen (add_file, "r");
  340.       if (add_fp == NULL)
  341.     {
  342.       printf ("%s: unable to open: %s\n", argv[0], add_file);
  343.       exit (-1);
  344.     }
  345.     }
  346.   
  347.   /*  open multiplicative scaling file. */
  348.   if (mult_file )
  349.     {
  350.       mult_fp = fopen (mult_file, "r");
  351.       if (mult_fp == NULL)
  352.     {
  353.       printf ("%s: unable to open: %s\n", argv[0], mult_file);
  354.       exit (-1);
  355.     }
  356.     }
  357.   
  358.   
  359.   /*  open file of data to be joined in. */
  360.   if (join_file )
  361.     {
  362.       join_fp = fopen (join_file, "r");
  363.       if (join_fp == NULL)
  364.     {
  365.       printf ("%s: unable to open: %s\n", argv[0], join_file);
  366.       exit (-1);
  367.     }
  368.     }
  369.   
  370.   
  371.   /*  skip data upto the offset datum. */
  372.   while (offset-- &&  read_ok)
  373.     {
  374.       read_ok = readit (&data, stdin);
  375.     }
  376.   
  377.   
  378.   while (read_ok )
  379.     {
  380.       int count = copy;
  381.       double mult_data, add_data;
  382.       while (count-- &&  read_ok)
  383.     {
  384.       read_ok = readit (&data, stdin);
  385.       if ( ! read_ok )
  386.         goto finish;
  387.       if (add_fp != NULL)
  388.         {
  389.           read_ok = readit (&add_data, add_fp);
  390.           if ( ! read_ok )
  391.         goto finish;
  392.           data += add_data;
  393.         }
  394.       if (mult_fp != NULL)
  395.         {
  396.           read_ok = readit (&mult_data, mult_fp);
  397.           if ( ! read_ok )
  398.         goto finish;
  399.           data *= mult_data;
  400.         }
  401.       data *= scale;
  402.       data += baseline;
  403.       if (data > max)
  404.         max = data;
  405.       if (data < min)
  406.         min = data;
  407.       
  408.       if (take_derivative)
  409.         {
  410.           double tmp = data;
  411.           if (last_data == LARGE)
  412.         data = last_data;
  413.           data -= last_data;
  414.           last_data = tmp;
  415.         }
  416.       if (! silent)
  417.         {
  418.           write_ok = writeit (&data, stdout);
  419.           if ( ! write_ok)
  420.         {
  421.           fprintf ( stderr, "double: unable to write to output.\n");
  422.           exit (-1);
  423.         }
  424.           if (join_fp != NULL)
  425.         {
  426.           read_ok = readit (&data, join_fp);
  427.           if (read_ok)
  428.             write_ok = writeit (&data, stdout);
  429.           if ( ! write_ok)
  430.             {
  431.               fprintf ( stderr, "double: unable to write to output.\n");
  432.               exit (-1);
  433.             }
  434.         }
  435.         }
  436.     }
  437.       count = skip;
  438.       while (count-- &&  read_ok)
  439.     {
  440.       read_ok = readit (&data, stdin);
  441.     }
  442.     }
  443.  finish:
  444.   if (do_max)
  445.     writeit (&max, stdout);
  446.   if (do_min)
  447.     writeit (&min, stdout);
  448.   return 0;
  449. }
  450.