home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / graphics-0.17 / graph / read_file.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-03-28  |  7.0 KB  |  258 lines

  1. /* plot, a set of unix plot utilities.
  2.    Copyright (C) 1989 Free Software Foundation, Inc.
  3.  
  4.    Plot is distributed in the hope that it will be useful, but WITHOUT
  5.    ANY WARRANTY.  No author or distributor accepts responsibility to
  6.    anyone for the consequences of using it or for whether it serves any
  7.    particular purpose or works at all, unless he says so in writing.
  8.    Refer to the GNU General Public License for full details.
  9.  
  10.    Everyone is granted permission to copy, modify and redistribute plot,
  11.    but only under the conditions described in the GNU General Public
  12.    License.  A copy of this license is supposed to have been given to you
  13.    along with plot so you can know your rights and responsibilities.  It
  14.    should be in a file named COPYING.  Among other things, the copyright
  15.    notice and this notice must be preserved on all copies.  */
  16.  
  17. /* This file is the main routine for graph. */
  18.  
  19. #include "sys-defines.h"
  20. #include "libplot.h"
  21. #include "extern.h"
  22.  
  23. /* read_number() reads a number form the specified stream.  The data
  24.    spec indicates how to read the number.  read_number returns 0 upon
  25.    end of file or error.  */
  26.  
  27. int
  28. read_number (stream, data_spec, value)
  29.      FILE *stream;
  30.      data_type data_spec;
  31.      float *value;
  32. {
  33.   int rc;            /* Return code        */
  34.   short short_val;        /* Holds short value    */
  35.   int int_val;            /* Holds int value    */
  36.   double double_val;        /* Holds double value    */
  37.  
  38.   /*
  39.    * Read the data according to the given data spec
  40.    */
  41.  
  42.   switch (data_spec)
  43.     {
  44.     case ASCII_DATA:
  45.       rc = fscanf (stream, "%f ", value);
  46.       if (rc == EOF) rc = 0;
  47.       break;
  48.     case INT_DATA:
  49.       rc = fread ((VOIDPTR *) & int_val, sizeof (int_val), 1, stream);
  50.       *value = (float) int_val;
  51.       break;
  52.     case SHORT_INT_DATA:
  53.       rc = fread ((VOIDPTR *) & short_val, sizeof (short_val), 1, stream);
  54.       *value = (float) short_val;
  55.       break;
  56.     case FLOAT_DATA:
  57.       rc = fread ((VOIDPTR *) value, sizeof (*value), 1, stream);
  58.       break;
  59.     case DOUBLE_DATA:
  60.       rc = fread ((VOIDPTR *) & double_val, sizeof (double_val), 1, stream);
  61.       *value = (float) double_val;
  62.       break;
  63.     }
  64.  
  65.   return rc;
  66. }
  67.  
  68. /* read_file reads a file of coordinates and labels from a specified
  69.    stream. It passes back x, y, and label arrays containing the data
  70.    read in and the size of the arrays. It returns the number of elements
  71.    read into the arrays. The size and number of elements read is equal
  72.    for all three arrays. */
  73.  
  74. int
  75. read_file (in_stream, p, length, no_of_points, auto_abscissa,
  76.        x_start, delta_x, data_spec, symbol_index, transpose_axes,
  77.        default_label, linemode, m_break_flag)
  78.      FILE *in_stream;
  79.      point_struct **p;
  80.      int *length;
  81.      int *no_of_points;
  82.      int auto_abscissa;
  83.      double x_start;
  84.      double delta_x;
  85.      data_type data_spec;
  86.      int symbol_index;
  87.      int transpose_axes;
  88.      char *default_label;
  89.      int linemode;
  90.      int m_break_flag;        /* non-zero means break when x decreases. */
  91. {
  92.   char *input_string;        /* buffer to hold a label */
  93.   int input_string_length;    /* length of input_string buffer */
  94.   char lookahead;        /* next character to be read */
  95.   int no_read = 1;        /* no of items last read. */
  96.   double abscissa;        /* counter for auto_abscissa */
  97.   int first_point;
  98.  
  99.   first_point = *no_of_points;    /* break at first point */
  100.   abscissa = x_start;
  101.   input_string_length = 1024;
  102.   input_string = (char *) do_malloc (input_string_length);
  103.  
  104.   while (!feof (in_stream) && (no_read > 0))
  105.     {
  106.       /*
  107.        * Grow the buffer if needed
  108.        */
  109.       if (*no_of_points >= *length)
  110.     {
  111.       *length *= 2;
  112.       (*p) = (point_struct *) do_realloc ((*p), *length * sizeof (point_struct));
  113.     }
  114.       /*
  115.        * Read in the data
  116.        */
  117.       if (auto_abscissa)
  118.     {
  119.       if (transpose_axes)
  120.         (*p)[*no_of_points].y = abscissa;
  121.       else
  122.         (*p)[*no_of_points].x = abscissa;
  123.       abscissa += delta_x;
  124.     }
  125.       else
  126.     {
  127.       if (transpose_axes)
  128.         no_read = read_number (in_stream, data_spec, &(*p)[*no_of_points].y);
  129.       else
  130.         no_read = read_number (in_stream, data_spec, &(*p)[*no_of_points].x);
  131.       if (no_read == 0 && data_spec == ASCII_DATA)
  132.         {
  133.           char *newline;
  134.  
  135.           fgets (input_string, input_string_length, in_stream);
  136.           newline = strchr(input_string, '\n');
  137.           if (newline != NULL)
  138.         *newline = '\0';
  139.           (void) fprintf (stderr,
  140.                   "%s:  error reading x coordinate at `%s'.\n",
  141.                   progname, input_string);
  142.           exit (-1);
  143.         }
  144.     }
  145.       if (transpose_axes)
  146.     no_read = read_number (in_stream, data_spec, &(*p)[*no_of_points].x);
  147.       else
  148.     no_read = read_number (in_stream, data_spec, &(*p)[*no_of_points].y);
  149.       if (no_read == 0 && data_spec == ASCII_DATA)
  150.     {
  151.       char *s;
  152.       fgets (input_string, input_string_length, in_stream);
  153.       s = strchr (input_string, '\n');
  154.       if (s) *s = '\0';
  155.       fprintf (stderr, "%s:  error reading y coordinate at `%s'.\n",
  156.            progname, input_string);
  157.       exit (-1);
  158.     }
  159.  
  160.       /* If we are reading ascii data, look for a label as well. */
  161.       if (data_spec != ASCII_DATA)
  162.     (*p)[*no_of_points].string = default_label;
  163.       else
  164.     {
  165.       lookahead = getc (in_stream);
  166.       ungetc (lookahead, in_stream);
  167.       if (isdigit (lookahead)
  168.           || (lookahead == EOF)
  169.           || (lookahead == '.')
  170.           || (lookahead == '+')
  171.           || (lookahead == '-'))
  172.         {
  173.           (*p)[*no_of_points].string = default_label;
  174.         }
  175.       else
  176.         {
  177.           int i = 0, again = 0, quoted = 0;
  178.           char last_char;
  179.  
  180.           if (lookahead == '"')
  181.         {
  182.           quoted = 1;
  183.           getc (in_stream);    /* skip double quote */
  184.         }
  185.           else
  186.         quoted = 0;
  187.  
  188.           do
  189.         {
  190.           last_char = getc (in_stream);
  191.           input_string[i] = last_char;
  192.           if (i >= (input_string_length - 1))
  193.             {
  194.               input_string_length *= 2;
  195.               input_string = (char *) do_realloc
  196.             (input_string, input_string_length * sizeof (char *));
  197.             }
  198.           if (last_char == '\\') /* backquote is the escape char */
  199.             {
  200.               last_char = getc (in_stream);
  201.               input_string[i] = last_char;
  202.               last_char = 0;    /* ignore the last char
  203.                        since it was escaped */
  204.             }
  205.           i++;
  206.           if (quoted)
  207.             {
  208.               if (last_char != '"')
  209.             again = 1;
  210.               else
  211.             again = 0;
  212.             }
  213.           else
  214.             {
  215.               switch (last_char)
  216.             {
  217.             case ' ':
  218.             case '\t':
  219.             case '\n':
  220.             case '\v':
  221.             case '\f':
  222.               again = 0;
  223.               break;
  224.             default:
  225.               again = 1;
  226.             }
  227.             }
  228.           } while (again && (last_char != EOF));
  229.  
  230.           input_string[i - 1] = '\0'; /* replace termination with null */
  231.           (*p)[*no_of_points].string
  232.         = (char *) do_malloc (strlen (input_string));
  233.           strcpy ((*p)[*no_of_points].string, input_string);
  234.         }
  235.     }
  236.       (*p)[*no_of_points].symbol = symbol_index;
  237.       if (no_of_points)
  238.     {
  239.       if (   m_break_flag
  240.           && ((*p)[*no_of_points-1].x > (*p)[*no_of_points].x))
  241.         {
  242.           (*p)[*no_of_points].linemode = -1;        
  243.           if (m_break_flag == 2)
  244.         linemode++;
  245.         }
  246.       else
  247.         (*p)[*no_of_points].linemode = linemode;
  248.     }
  249.       if (no_read > 0)
  250.     (*no_of_points)++;
  251.     }
  252.  
  253.   if (*no_of_points > first_point) /* break the line at the first point */
  254.     (*p)[first_point].linemode = -1;
  255.   free (input_string);
  256.   return *no_of_points;
  257. }
  258.