COIN-OR::LEMON - Graph Library

source: glpk-cmake/src/glpsdf.c

Last change on this file was 1:c445c931472f, checked in by Alpar Juttner <alpar@…>, 13 years ago

Import glpk-4.45

  • Generated files and doc/notes are removed
File size: 7.0 KB
Line 
1/* glpsdf.c (plain data file reading routines) */
2
3/***********************************************************************
4*  This code is part of GLPK (GNU Linear Programming Kit).
5*
6*  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
7*  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
8*  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
9*  E-mail: <mao@gnu.org>.
10*
11*  GLPK is free software: you can redistribute it and/or modify it
12*  under the terms of the GNU General Public License as published by
13*  the Free Software Foundation, either version 3 of the License, or
14*  (at your option) any later version.
15*
16*  GLPK is distributed in the hope that it will be useful, but WITHOUT
17*  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
18*  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
19*  License for more details.
20*
21*  You should have received a copy of the GNU General Public License
22*  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
23***********************************************************************/
24
25#define GLPSDF_H
26
27#define GLP_DATA_DEFINED
28typedef struct glp_data glp_data;
29
30#include "glpapi.h"
31
32struct glp_data
33{     /* plain data file */
34      char *fname;
35      /* name of data file */
36      XFILE *fp;
37      /* stream assigned to data file */
38      void *jump; /* jmp_buf jump; */
39      /* label for go to in case of error */
40      int count;
41      /* line count */
42      int c;
43      /* current character of XEOF */
44      char item[255+1];
45      /* current data item */
46};
47
48static void next_char(glp_data *data);
49
50glp_data *glp_sdf_open_file(const char *fname)
51{     /* open plain data file */
52      glp_data *data = NULL;
53      XFILE *fp;
54      jmp_buf jump;
55      fp = xfopen(fname, "r");
56      if (fp == NULL)
57      {  xprintf("Unable to open `%s' - %s\n", fname, xerrmsg());
58         goto done;
59      }
60      data = xmalloc(sizeof(glp_data));
61      data->fname = xmalloc(strlen(fname)+1);
62      strcpy(data->fname, fname);
63      data->fp = fp;
64      data->jump = NULL;
65      data->count = 0;
66      data->c = '\n';
67      data->item[0] = '\0';
68      /* read the very first character */
69      if (setjmp(jump))
70      {  glp_sdf_close_file(data);
71         data = NULL;
72         goto done;
73      }
74      data->jump = jump;
75      next_char(data);
76      data->jump = NULL;
77done: return data;
78}
79
80void glp_sdf_set_jump(glp_data *data, void *jump)
81{     /* set up error handling */
82      data->jump = jump;
83      return;
84}
85
86void glp_sdf_error(glp_data *data, const char *fmt, ...)
87{     /* print error message */
88      va_list arg;
89      xprintf("%s:%d: ", data->fname, data->count);
90      va_start(arg, fmt);
91      xvprintf(fmt, arg);
92      va_end(arg);
93      if (data->jump == NULL)
94         xerror("");
95      else
96         longjmp(data->jump, 1);
97      /* no return */
98}
99
100void glp_sdf_warning(glp_data *data, const char *fmt, ...)
101{     /* print warning message */
102      va_list arg;
103      xprintf("%s:%d: warning: ", data->fname, data->count);
104      va_start(arg, fmt);
105      xvprintf(fmt, arg);
106      va_end(arg);
107      return;
108}
109
110static void next_char(glp_data *data)
111{     /* read next character */
112      int c;
113      if (data->c == XEOF)
114         glp_sdf_error(data, "unexpected end of file\n");
115      else if (data->c == '\n')
116         data->count++;
117      c = xfgetc(data->fp);
118      if (c < 0)
119      {  if (xferror(data->fp))
120            glp_sdf_error(data, "read error - %s\n", xerrmsg());
121         else if (data->c == '\n')
122            c = XEOF;
123         else
124         {  glp_sdf_warning(data, "missing final end of line\n");
125            c = '\n';
126         }
127      }
128      else if (c == '\n')
129         ;
130      else if (isspace(c))
131         c = ' ';
132      else if (iscntrl(c))
133         glp_sdf_error(data, "invalid control character 0x%02X\n", c);
134      data->c = c;
135      return;
136}
137
138static void skip_pad(glp_data *data)
139{     /* skip uninteresting characters and comments */
140loop: while (data->c == ' ' || data->c == '\n')
141         next_char(data);
142      if (data->c == '/')
143      {  next_char(data);
144         if (data->c != '*')
145            glp_sdf_error(data, "invalid use of slash\n");
146         next_char(data);
147         for (;;)
148         {  if (data->c == '*')
149            {  next_char(data);
150               if (data->c == '/')
151               {  next_char(data);
152                  break;
153               }
154            }
155            next_char(data);
156         }
157         goto loop;
158      }
159      return;
160}
161
162static void next_item(glp_data *data)
163{     /* read next item */
164      int len;
165      skip_pad(data);
166      len = 0;
167      while (!(data->c == ' ' || data->c == '\n'))
168      {  data->item[len++] = (char)data->c;
169         if (len == sizeof(data->item))
170            glp_sdf_error(data, "data item `%.31s...' too long\n",
171               data->item);
172         next_char(data);
173      }
174      data->item[len] = '\0';
175      return;
176}
177
178int glp_sdf_read_int(glp_data *data)
179{     /* read integer number */
180      int x;
181      next_item(data);
182      switch (str2int(data->item, &x))
183      {  case 0:
184            break;
185         case 1:
186            glp_sdf_error(data, "integer `%s' out of range\n",
187               data->item);
188         case 2:
189            glp_sdf_error(data, "cannot convert `%s' to integer\n",
190               data->item);
191         default:
192            xassert(data != data);
193      }
194      return x;
195}
196
197double glp_sdf_read_num(glp_data *data)
198{     /* read floating-point number */
199      double x;
200      next_item(data);
201      switch (str2num(data->item, &x))
202      {  case 0:
203            break;
204         case 1:
205            glp_sdf_error(data, "number `%s' out of range\n",
206               data->item);
207         case 2:
208            glp_sdf_error(data, "cannot convert `%s' to number\n",
209               data->item);
210         default:
211            xassert(data != data);
212      }
213      return x;
214}
215
216const char *glp_sdf_read_item(glp_data *data)
217{     /* read data item */
218      next_item(data);
219      return data->item;
220}
221
222const char *glp_sdf_read_text(glp_data *data)
223{     /* read text until end of line */
224      int c, len = 0;
225      for (;;)
226      {  c = data->c;
227         next_char(data);
228         if (c == ' ')
229         {  /* ignore initial spaces */
230            if (len == 0) continue;
231            /* and multiple ones */
232            if (data->item[len-1] == ' ') continue;
233         }
234         else if (c == '\n')
235         {  /* remove trailing space */
236            if (len > 0 && data->item[len-1] == ' ') len--;
237            /* and stop reading */
238            break;
239         }
240         /* add current character to the buffer */
241         data->item[len++] = (char)c;
242         if (len == sizeof(data->item))
243            glp_sdf_error(data, "line too long\n", data->item);
244      }
245      data->item[len] = '\0';
246      return data->item;
247}
248
249int glp_sdf_line(glp_data *data)
250{     /* determine current line number */
251      return data->count;
252}
253
254void glp_sdf_close_file(glp_data *data)
255{     /* close plain data file */
256      xfclose(data->fp);
257      xfree(data->fname);
258      xfree(data);
259      return;
260}
261
262/* eof */
Note: See TracBrowser for help on using the repository browser.