1 /****************************************************************
2 Copyright (C) 1997, 1999,2000 Lucent Technologies
3 All Rights Reserved
4
5 Permission to use, copy, modify, and distribute this software and
6 its documentation for any purpose and without fee is hereby
7 granted, provided that the above copyright notice appear in all
8 copies and that both that the copyright notice and this
9 permission notice and warranty disclaimer appear in supporting
10 documentation, and that the name of Lucent or any of its entities
11 not be used in advertising or publicity pertaining to
12 distribution of the software without specific, written prior
13 permission.
14
15 LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
16 INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
17 IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
18 SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
20 IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
21 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
22 THIS SOFTWARE.
23 ****************************************************************/
24
25 #include "nlp.h"
26
27 #define MSGGULP 1024
28
29 typedef struct
30 msginfo {
31 char *msg;
32 char *msg0;
33 char *msgend;
34 ftnlen msglen;
35 } msginfo;
36
37 static void
38 #ifdef KR_headers
msgput(m,b,n)39 msgput(m, b, n) msginfo *m; char *b; int n;
40 #else
41 msgput(msginfo *m, char *b, int n)
42 #endif
43 {
44 char *be, *msg, *msg0, *msgend;
45 ftnlen msglen0;
46
47 msg = m->msg;
48 msgend = m->msgend;
49 be = b + n;
50 while(b < be) {
51 if (msg >= msgend) {
52 msglen0 = m->msglen;
53 msg0 = m->msg0 = (char*)
54 Realloc(m->msg0, m->msglen += MSGGULP);
55 msg = msg0 + msglen0;
56 m->msgend = msg0 + m->msglen;
57 }
58 *msg++ = *b++;
59 }
60 m->msg = msg;
61 }
62
63 static void
64 #ifdef KR_headers
badnumber(asl,a,b,what)65 badnumber(asl, a, b, what) ASL *asl; fint a, b; char *what;
66 #else
67 badnumber(ASL *asl, fint a, fint b, char *what)
68 #endif
69 {
70 fprintf(Stderr, "%s indicates %ld rather than %ld %s\n",
71 filename, (long)a, (long)b, what);
72 fflush(Stderr);
73 }
74
75 static int
76 #ifdef KR_headers
decstring(buf,val)77 decstring(buf, val) char *buf; real *val;
78 #else
79 decstring(char *buf, real *val)
80 #endif
81 {
82 char *be;
83 register int c;
84
85 *val = strtod(buf, &be);
86 return be <= buf || ((c = be[-1]) < '0' || c > '9') && c != '.';
87 }
88
89 char *
90 #ifdef KR_headers
read_sol_ASL(asl,xp,yp)91 read_sol_ASL(asl, xp, yp) ASL *asl; real **xp, **yp;
92 #else
93 read_sol_ASL(ASL *asl, real **xp, real **yp)
94 #endif
95 {
96 int binary, flag1, i, j, je, n, need_vbtol;
97 FILE *f;
98 char buf[512], *s, *se;
99 real vbtol, *y;
100 ftnlen L, L1, L2;
101 fint Objno[2], nOpts, *z;
102 msginfo mi;
103
104 if (!asl || asl->i.ASLtype < 1 || asl->i.ASLtype > 5)
105 badasl_ASL(asl,0,"read_soln");
106 strcpy(stub_end, ".sol");
107 f = fopen(filename, "rb");
108 if (!f) {
109 fprintf(Stderr, "Can't open %s\n", filename);
110 fflush(Stderr);
111 return 0;
112 }
113 if (fread(&L, sizeof(ftnlen), 1, f) && L == 6) {
114 /* binary files may be written by Fortran unformatted writes */
115 binary = 1;
116 if (!fread(buf, 6, 1, f)
117 || strncmp(buf,"binary",6)
118 || !fread(&L, sizeof(ftnlen), 1, f)
119 || L != 6) {
120 badbinary:
121 fprintf(Stderr, "bad binary file %s\n", filename);
122 fflush(Stderr);
123 goto done;
124 }
125 }
126 else {
127 binary = 0;
128 rewind(f);
129 }
130
131 /* Read termination msg */
132 nOpts = i = need_vbtol = 0;
133 mi.msg = mi.msg0 = (char *)Malloc(mi.msglen = MSGGULP);
134 mi.msgend = mi.msg0 + MSGGULP;
135 if (binary) {
136 for(;; i++) {
137 if (!fread(&L,sizeof(ftnlen),1,f))
138 goto early_eof;
139 if (L1 = L) {
140 do {
141 n = L < sizeof(buf) ? (int)L : (int)sizeof(buf);
142 L -= n;
143 if (!fread(buf, n, 1, f))
144 goto early_eof;
145 if (!L) {
146 while(--n >= 0 && buf[n] == ' ');
147 n++;
148 }
149 msgput(&mi, buf, n);
150 }
151 while(L);
152 msgput(&mi, "\n", 1);
153 }
154 if (!fread(&L, sizeof(ftnlen), 1, f))
155 goto early_eof;
156 if (L != L1)
157 goto badbinary;
158 if (!L)
159 break;
160 }
161 L1 = n_con * sizeof(real);
162 if (!fread(&L, sizeof(ftnlen), 1, f))
163 goto badbinary;
164 if (L == 8*sizeof(fint) + 7
165 || L == 9*sizeof(fint) + 7
166 || L == 8*sizeof(fint) + 7 + sizeof(real)
167 || L == 9*sizeof(fint) + 7 + sizeof(real)) {
168 /* check for Options */
169 if (!fread(buf, 7, 1, f))
170 goto badbinary;
171 if (strncmp(buf, "Options", 7))
172 goto badbinary;
173 if (!fread(&nOpts, sizeof(fint), 1, f))
174 goto badbinary;
175 if (nOpts < 3 || nOpts > 6) {
176 bad_nOpts:
177 fprintf(Stderr,
178 "expected nOpts between 3 and 6; got %ld: ",
179 (long)nOpts);
180 goto badbinary;
181 }
182 if (nOpts > 4) {
183 nOpts -= 2;
184 need_vbtol = 1;
185 }
186 if (!fread((ampl_options+1), sizeof(fint),
187 (size_t)(nOpts+4), f))
188 goto badbinary;
189 if (need_vbtol
190 && !fread(&vbtol, sizeof(real), 1, f))
191 goto badbinary;
192 if (!fread(&L2, sizeof(ftnlen), 1, f)
193 || L != L2)
194 goto badbinary;
195 }
196 else if (L != L1)
197 goto badbinary;
198 }
199 else {
200 for(;; i++) {
201 if (!fgets(buf, sizeof(buf), f)) {
202 early_eof:
203 fprintf(Stderr,
204 "early end of file reading %s\n",
205 filename);
206 fflush(Stderr);
207 done:
208 fclose(f);
209 return 0;
210 }
211 if (*buf == '\n' || *buf == '\r' && buf[1] == '\n')
212 break;
213 msgput(&mi, buf, strlen(buf));
214 }
215 while((j = getc(f)) == '\n');
216 if (j != 'O')
217 ungetc(j,f);
218 else {
219 if (!fgets(buf, sizeof(buf), f))
220 goto early_eof;
221 if (!strncmp(buf, "ptions", 6)) {
222 if (!fgets(buf, sizeof(buf), f))
223 goto early_eof;
224 nOpts = strtol(buf,&se,10);
225 if (se == buf)
226 goto badline;
227 if (nOpts < 3 || nOpts > 6)
228 goto bad_nOpts;
229 if (nOpts > 4) {
230 nOpts -= 2;
231 need_vbtol = 1;
232 }
233 je = (int)nOpts + 4;
234 for(j = 1; j <= je; j++) {
235 if (!fgets(buf, sizeof(buf), f))
236 goto early_eof;
237 ampl_options[j] = strtol(buf,&se,10);
238 if (se == buf)
239 goto badline;
240 }
241 if (need_vbtol && !fgets(buf, sizeof(buf), f))
242 goto early_eof;
243 /* We don't do anything here with vbtol, */
244 /* so we don't bother converting it. */
245 }
246 }
247 }
248 msgput(&mi, "", 1); /* add null to end */
249
250 if (i)
251 fflush(stdout);
252
253 if (ampl_options[0] = nOpts) {
254 z = ampl_options + nOpts + 1;
255 j = (int)z[3];
256 if (j > n_var || j < 0) {
257 badnumber(asl, j, n_var, "variables");
258 goto done;
259 }
260 j = (int)z[1];
261 if (j > n_con || j < 0) {
262 badnumber(asl, j, n_con, "constraints");
263 goto done;
264 }
265 if (binary) {
266 L1 = j * sizeof(real);
267 if (!fread(&L, sizeof(ftnlen), 1, f))
268 goto badbinary;
269 if (L != L1)
270 goto badbinary;
271 }
272 }
273 else
274 j = n_con;
275 if (!j) {
276 *yp = 0;
277 goto get_x;
278 }
279 y = *yp = (real *)Malloc(n_con * sizeof(real));
280 if (binary) {
281 if (fread(y, sizeof(real), j, f) != j)
282 goto early_eof;
283 if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1)
284 goto badbinary;
285 y += j;
286 }
287 else for(i = 0; i < j; i++) {
288 if (!fgets(buf, sizeof(buf), f))
289 goto early_eof;
290 if (!decstring(buf, y++))
291 continue;
292 badline:
293 fprintf(Stderr, "bad line in %s: %s", filename, buf);
294 fflush(Stderr);
295 goto done;
296 }
297 y = *yp;
298 while(j < n_con)
299 y[j++] = 0;
300 get_x:
301 Objno[0] = 0;
302 Objno[1] = -1;
303 flag1 = asl->i.flags & ~1;;
304 if (!(j = nOpts ? (int)z[3] : n_var)) {
305 *xp = 0;
306 goto ret;
307 }
308 y = *xp = (real *)Malloc(n_var*sizeof(real));
309
310 if (binary) {
311 L1 = j * sizeof(real);
312 if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1)
313 goto badbinary;
314 if (fread(y, sizeof(real), j, f) != j)
315 goto early_eof;
316 y += j;
317 /* do we have an obj_no ? */
318 if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1)
319 goto badbinary;
320 if (fread(&L, sizeof(ftnlen), 1, f)) {
321 i = 1;
322 if (L == 2*sizeof(fint)) {
323 i = 2;
324 flag1 |= 1;
325 }
326 else if (L != sizeof(fint))
327 goto badbinary;
328 if (!fread(Objno, i*sizeof(fint), 1, f))
329 goto badbinary;
330 }
331 }
332 else {
333 for(i = j; i > 0; i--) {
334 if (!fgets(buf, sizeof(buf), f))
335 goto early_eof;
336 if (decstring(buf, y++))
337 goto badline;
338 }
339 if (fgets(buf,sizeof(buf), f)) {
340 if (strncmp(buf,"objno ",6)) {
341 extra_line:
342 fprintf(Stderr, "Bug: extra line in %s:\n%s",
343 filename, buf);
344 fflush(Stderr);
345 }
346 else {
347 Objno[0] = strtol(buf+6, &se, 10);
348 if (se == buf+6 || *se > ' ')
349 goto extra_line;
350 if (*se == ' ') {
351 Objno[1] = strtol(se,&s,10);
352 if (s == se || *s > ' ')
353 goto extra_line;
354 flag1 |= 1;
355 }
356 }
357 }
358 }
359 asl->i.flags = flag1;
360 obj_no = (int)Objno[0];
361 solve_result_num = (int)Objno[1];
362 y = *xp;
363 while(j < n_var)
364 y[j++] = 0;
365 ret:
366 fclose(f);
367 return (char*)Realloc(mi.msg0, mi.msglen);
368 }
369