lemon-project-template-glpk
comparison deps/glpk/src/glpsdf.c @ 9:33de93886c88
Import GLPK 4.47
author | Alpar Juttner <alpar@cs.elte.hu> |
---|---|
date | Sun, 06 Nov 2011 20:59:10 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:2945435f1968 |
---|---|
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, 2011 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 | |
28 typedef struct glp_data glp_data; | |
29 | |
30 #include "glpapi.h" | |
31 | |
32 struct 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 | |
48 static void next_char(glp_data *data); | |
49 | |
50 glp_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; | |
77 done: return data; | |
78 } | |
79 | |
80 void glp_sdf_set_jump(glp_data *data, void *jump) | |
81 { /* set up error handling */ | |
82 data->jump = jump; | |
83 return; | |
84 } | |
85 | |
86 void 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 | |
100 void 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 | |
110 static 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 | |
138 static void skip_pad(glp_data *data) | |
139 { /* skip uninteresting characters and comments */ | |
140 loop: 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 | |
162 static 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 | |
178 int 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 | |
197 double 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 | |
216 const char *glp_sdf_read_item(glp_data *data) | |
217 { /* read data item */ | |
218 next_item(data); | |
219 return data->item; | |
220 } | |
221 | |
222 const 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 | |
249 int glp_sdf_line(glp_data *data) | |
250 { /* determine current line number */ | |
251 return data->count; | |
252 } | |
253 | |
254 void 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 */ |