read.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:8k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /* $Header: /usr/src/mash/repository/vint/xgraph/read.c,v 1.2 1999/12/03 23:17:45 heideman Exp $ */
  2. /*
  3.  * read.c: Dataset read code
  4.  *
  5.  * Routines:
  6.  * int ReadData();
  7.  *
  8.  * $Log: read.c,v $
  9.  * Revision 1.2  1999/12/03 23:17:45  heideman
  10.  * apply xgraph_no_animation.patch
  11.  *
  12.  * Revision 1.1.1.1  1999/12/03 23:15:53  heideman
  13.  * xgraph-12.0
  14.  *
  15.  */
  16. #ifndef lint
  17. static char rcsid[] = "$Id: read.c,v 1.2 1999/12/03 23:17:45 heideman Exp $";
  18. #endif
  19. #include "copyright.h"
  20. #include <stdio.h>
  21. #include <math.h>
  22. #include <pwd.h>
  23. #include <ctype.h>
  24. #include "xgraph.h"
  25. #include "xtb.h"
  26. #include "hard_devices.h"
  27. #include "params.h"
  28. /*
  29.  * New dataset reading code
  30.  */
  31. static int setNumber = 0;
  32. static PointList **curSpot = (PointList **) 0;
  33. static PointList *curList = (PointList *) 0;
  34. static int newGroup = 0;
  35. static int redundant_set = 0;
  36. #ifdef DO_DER
  37. extern void Der1();
  38. #endif
  39. static int
  40. rdSet(fn)
  41. char   *fn; /* Reading from file `fn' */
  42. /*
  43.  * Set up new dataset.  Will return zero if there are too many data sets.
  44.  */
  45. {
  46.     char    setname[100];
  47.     if (!redundant_set) {
  48. if (setNumber < MAXSETS) {
  49.     (void) sprintf(setname, "Set %d", setNumber);
  50.     if ((strcmp(PlotData[setNumber].setName, setname) == 0) && fn) {
  51. PlotData[setNumber].setName = fn;
  52.     }
  53.     curSpot = &(PlotData[setNumber].list);
  54.     PlotData[setNumber].list = (PointList *) 0;
  55.     newGroup = 1;
  56.     setNumber++;
  57.     redundant_set = 1;
  58.     return 1;
  59. }
  60. else {
  61.     return 0;
  62. }
  63.     }
  64.     else {
  65. return 1;
  66.     }
  67. }
  68. static void
  69. rdSetName(name)
  70. char   *name; /* New set name */
  71. /*
  72.  * Sets the name of a data set.  Automatically makes a copy.
  73.  */
  74. {
  75.     PlotData[setNumber - 1].setName = STRDUP(name);
  76. }
  77. static void
  78. rdGroup()
  79. /*
  80.  * Set up for reading new group of points within a dataset.
  81.  */
  82. {
  83.     newGroup = 1;
  84. }
  85. static void
  86. rdPoint(xval, yval)
  87. double  xval,
  88.         yval; /* New point         */
  89. /*
  90.  * Adds a new point to the current group of the current
  91.  * data set.
  92.  */
  93. {
  94.     if (newGroup) {
  95. *curSpot = (PointList *) Malloc(sizeof(PointList));
  96. curList = *curSpot;
  97. curSpot = &(curList->next);
  98. curList->numPoints = 0;
  99. curList->allocSize = INITSIZE;
  100. curList->xvec = (double *) Malloc((unsigned)
  101.   (INITSIZE * sizeof(double)));
  102. curList->yvec = (double *) Malloc((unsigned)
  103.   (INITSIZE * sizeof(double)));
  104. curList->next = (PointList *) 0;
  105. newGroup = 0;
  106.     }
  107.     if (curList->numPoints >= curList->allocSize) {
  108. curList->allocSize *= 2;
  109. curList->xvec = (double *) Realloc((char *) curList->xvec,
  110.    (unsigned) (curList->allocSize *
  111.        sizeof(double)));
  112. curList->yvec = (double *) Realloc((char *) curList->yvec,
  113.    (unsigned) (curList->allocSize *
  114.        sizeof(double)));
  115.     }
  116.     curList->xvec[curList->numPoints] = xval;
  117.     curList->yvec[curList->numPoints] = yval;
  118.     (curList->numPoints)++;
  119.     redundant_set = 0;
  120. }
  121. static int
  122. rdFindMax()
  123. /*
  124.  * Returns the maximum number of items in any one group of any
  125.  * data set.
  126.  */
  127. {
  128.     int     i;
  129.     PointList *list;
  130.     int     max = -1;
  131.     for (i = 0; i < setNumber; i++) {
  132. for (list = PlotData[i].list; list; list = list->next) {
  133.     if (list->numPoints > max)
  134. max = list->numPoints;
  135. }
  136.     }
  137.     return max;
  138. }
  139. typedef enum line_type {
  140.     EMPTY, COMMENT, SETNAME, DRAWPNT, MOVEPNT, SETPARAM, ERROR
  141. }       LineType;
  142. typedef struct point_defn {
  143.     double  xval,
  144.             yval;
  145. }       Point;
  146. typedef struct parmval_defn {
  147.     char   *name,
  148.            *value;
  149. }       ParmVals;
  150. typedef struct line_info {
  151.     LineType type;
  152.     union val_defn {
  153. char   *str; /* SETNAME, ERROR   */
  154. Point   pnt; /* DRAWPNT, MOVEPNT */
  155. ParmVals parm; /* SETPARAM         */
  156.     }       val;
  157. }       LineInfo;
  158. static  LineType
  159. parse_line(line, result)
  160. char   *line; /* Line to parse   */
  161. LineInfo *result; /* Returned result */
  162. /*
  163.  * Parses `line' into one of the types given in the definition
  164.  * of LineInfo.  The appropriate values are filled into `result'.
  165.  * Below are the current formats for each type:
  166.  *   EMPTY: All white space
  167.  *   COMMENT: Starts with "#"
  168.  *   SETNAME: A name enclosed in double quotes
  169.  *   DRAWPNT: Two numbers optionally preceded by keyword "draw"
  170.  *   MOVEPNT: Two numbers preceded by keyword "move"
  171.  *   SETPARAM:  Two non-null strings separated by ":"
  172.  *   ERROR: Not any of the above (an error message is returned)
  173.  * Note that often the values are pointers into the line itself
  174.  * and should be copied if they are to be used over a long period.
  175.  */
  176. {
  177.     char   *first;
  178.     /* Find first non-space character */
  179.     while (*line && isspace(*line))
  180. line++;
  181.     if (*line) {
  182. if (*line == '#') {
  183.     /* comment */
  184.     result->type = COMMENT;
  185. }
  186. else if (*line == '"') {
  187.     /* setname */
  188.     result->type = SETNAME;
  189.     line++;
  190.     result->val.str = line;
  191.     while (*line && (*line != 'n') && (*line != '"'))
  192. line++;
  193.     if (*line)
  194. *line = '';
  195. }
  196. else {
  197.     first = line;
  198.     while (*line && !isspace(*line))
  199. line++;
  200.     if (*line) {
  201. *line = '';
  202. if (stricmp(first, "move") == 0) {
  203.     /* MOVEPNT */
  204.     if (sscanf(line + 1, "%lf %lf",
  205.        &result->val.pnt.xval,
  206.        &result->val.pnt.yval) == 2) {
  207. result->type = MOVEPNT;
  208.     }
  209.     else {
  210. result->type = ERROR;
  211. result->val.str = "Cannot read move coordinates";
  212.     }
  213. }
  214. else if (stricmp(first, "draw") == 0) {
  215.     /* DRAWPNT */
  216.     if (sscanf(line + 1, "%lf %lf",
  217.        &result->val.pnt.xval,
  218.        &result->val.pnt.yval) == 2) {
  219. result->type = DRAWPNT;
  220.     }
  221.     else {
  222. result->type = ERROR;
  223. result->val.str = "Cannot read draw coordinates";
  224.     }
  225. }
  226. else if (first[strlen(first) - 1] == ':') {
  227.     /* SETPARAM */
  228.     first[strlen(first) - 1] = '';
  229.     result->val.parm.name = first;
  230.     line++;
  231.     while (*line && isspace(*line))
  232. line++;
  233.     /* may be a n at end of it */
  234.     if (line[strlen(line) - 1] == 'n') {
  235. line[strlen(line) - 1] = '';
  236.     }
  237.     result->val.parm.value = line;
  238.     result->type = SETPARAM;
  239. }
  240. else if (sscanf(first, "%lf", &result->val.pnt.xval) == 1) {
  241.     /* DRAWPNT */
  242.     if (sscanf(line + 1, "%lf", &result->val.pnt.yval) == 1) {
  243. result->type = DRAWPNT;
  244.     }
  245.     else {
  246. result->type = ERROR;
  247. result->val.str = "Cannot read second coordinate";
  248.     }
  249. }
  250. else {
  251.     /* ERROR */
  252.     result->type = ERROR;
  253.     result->val.str = "Unknown line type";
  254. }
  255.     }
  256.     else {
  257. /* ERROR */
  258. result->type = ERROR;
  259. result->val.str = "Premature end of line";
  260.     }
  261. }
  262.     }
  263.     else {
  264. /* empty */
  265. result->type = EMPTY;
  266.     }
  267.     return result->type;
  268. }
  269. int
  270. ReadData(stream, filename)
  271. FILE   *stream;
  272. char   *filename;
  273. /*
  274.  * Reads in the data sets from the supplied stream.  If the format
  275.  * is correct,  it returns the current maximum number of points across
  276.  * all data sets.  If there is an error,  it returns -1.
  277.  */
  278. {
  279.     char    buffer[MAXBUFSIZE];
  280.     LineInfo info;
  281.     int     line_count = 0;
  282.     int     errors = 0;
  283.     if (!rdSet(filename)) {
  284. (void) fprintf(stderr, "Error in file `%s' at line %d:n  %sn",
  285.        filename, line_count,
  286.        "Too many data sets - extra data ignored");
  287. return -1;
  288.     }
  289.     while (fgets(buffer, MAXBUFSIZE, stream)) {
  290. line_count++;
  291. switch (parse_line(buffer, &info)) {
  292. case EMPTY:
  293.     if (!rdSet(filename)) {
  294. (void) fprintf(stderr, "Error in file `%s' at line %d:n  %sn",
  295.        filename, line_count,
  296.        "Too many data sets - extra data ignored");
  297. return -1;
  298.     }
  299.     break;
  300. case COMMENT:
  301.     /* nothing */
  302.     break;
  303. case SETNAME:
  304.     rdSetName(info.val.str);
  305.     break;
  306. case DRAWPNT:
  307.     rdPoint(info.val.pnt.xval, info.val.pnt.yval);
  308.     break;
  309. case MOVEPNT:
  310.     rdGroup();
  311.     rdPoint(info.val.pnt.xval, info.val.pnt.yval);
  312.     break;
  313. case SETPARAM:
  314.     param_reset(info.val.parm.name, info.val.parm.value);
  315.     break;
  316. default:
  317.     if (filename) {
  318. (void) fprintf(stderr, "Error in file `%s' at line %d:n  %sn",
  319.        filename, line_count, info.val.str);
  320. errors++;
  321.     }
  322.     break;
  323. }
  324.     }
  325. #ifdef DO_DER
  326.     Der1();
  327. #endif
  328.     if (errors)
  329. return -1;
  330.     else
  331. return rdFindMax();
  332. }