1 |
/* |
2 |
* Discrete Variable Module |
3 |
* by Vicente Rico-Ramirez |
4 |
* Created: 06/96 |
5 |
* Version: $Revision: 1.12 $ |
6 |
* Version control file: $RCSfile: discrete.c,v $ |
7 |
* Date last modified: $Date: 1998/02/05 15:59:21 $ |
8 |
* Last modified by: $Author: ballan $ |
9 |
* |
10 |
* This file is part of the SLV solver. |
11 |
* |
12 |
* The SLV solver is free software; you can redistribute |
13 |
* it and/or modify it under the terms of the GNU General Public License as |
14 |
* published by the Free Software Foundation; either version 2 of the |
15 |
* License, or (at your option) any later version. |
16 |
* |
17 |
* The SLV solver is distributed in hope that it will be |
18 |
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
20 |
* General Public License for more details. |
21 |
* |
22 |
* You should have received a copy of the GNU General Public License |
23 |
* along with the program; if not, write to the Free Software Foundation, |
24 |
* Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named |
25 |
* COPYING. COPYING is found in ../compiler. |
26 |
* |
27 |
*/ |
28 |
|
29 |
#include "utilities/ascConfig.h" |
30 |
#include "utilities/ascMalloc.h" |
31 |
#include "general/list.h" |
32 |
#include "general/dstring.h" |
33 |
#include "compiler/compiler.h" |
34 |
#include "compiler/instance_enum.h" |
35 |
#include "compiler/module.h" |
36 |
#include "compiler/library.h" |
37 |
#include "compiler/symtab.h" |
38 |
#include "compiler/child.h" |
39 |
#include "compiler/fractions.h" |
40 |
#include "compiler/dimen.h" |
41 |
#include "compiler/type_desc.h" |
42 |
#include "compiler/atomvalue.h" |
43 |
#include "compiler/parentchild.h" |
44 |
#include "compiler/instquery.h" |
45 |
#include "compiler/instance_io.h" |
46 |
#include "solver/mtx.h" |
47 |
#include "solver/slv_types.h" |
48 |
#include "solver/var.h" |
49 |
#include "solver/rel.h" |
50 |
#include "solver/discrete.h" |
51 |
#include "solver/conditional.h" |
52 |
#include "solver/logrel.h" |
53 |
#include "solver/bnd.h" |
54 |
#include "solver/linsol.h" |
55 |
#include "solver/linsolqr.h" |
56 |
#include "solver/slv_server.h" |
57 |
#include "solver/slv_common.h" |
58 |
#include "solver/slv_client.h" |
59 |
#include "solver/analyze.h" |
60 |
|
61 |
|
62 |
#ifndef IPTR |
63 |
#define IPTR(i) ((struct Instance *)(i)) |
64 |
#endif |
65 |
|
66 |
/* useful symbol table things to know */ |
67 |
#define FIXED_V g_strings[0] |
68 |
#define NOMINAL_V g_strings[1] |
69 |
|
70 |
/* |
71 |
* array of those symbol table entries we need. |
72 |
*/ |
73 |
static symchar * g_strings[2]; |
74 |
|
75 |
static const struct dis_discrete g_dis_defaults = { |
76 |
e_dis_error_t, /* kind */ |
77 |
NULL, /* instance datom */ |
78 |
NULL, /* sos */ |
79 |
NULL, /* source */ |
80 |
NULL, /* whens */ |
81 |
-1, /* range */ |
82 |
-1, /* value */ |
83 |
-1, /* pre_value */ |
84 |
-1, /* mindex */ |
85 |
-1, /* sindex */ |
86 |
0 /* flags */ |
87 |
}; |
88 |
|
89 |
|
90 |
static struct dis_discrete *dis_copy(const struct dis_discrete *dis) |
91 |
{ |
92 |
struct dis_discrete *newdis; |
93 |
newdis = (struct dis_discrete *)ascmalloc( sizeof(struct dis_discrete) ); |
94 |
*newdis = *dis; |
95 |
return(newdis); |
96 |
} |
97 |
|
98 |
|
99 |
struct dis_discrete *dis_create(SlvBackendToken instance, |
100 |
struct dis_discrete *newdis) |
101 |
{ |
102 |
if (newdis==NULL) { |
103 |
newdis = dis_copy(&g_dis_defaults); /* malloc the discrete var */ |
104 |
} else { |
105 |
*newdis = g_dis_defaults; /* init the space we've been sent */ |
106 |
} |
107 |
assert(newdis!=NULL); |
108 |
newdis->datom = instance; |
109 |
return(newdis); |
110 |
} |
111 |
|
112 |
|
113 |
SlvBackendToken dis_instanceF(const struct dis_discrete *dis) |
114 |
{ if (dis==NULL || dis->datom==NULL) { |
115 |
FPRINTF(stderr,"dis_instance called on bad dvar\n"); |
116 |
return NULL; |
117 |
} |
118 |
return dis->datom; |
119 |
} |
120 |
|
121 |
void dis_set_instanceF(struct dis_discrete *dis, SlvBackendToken i) |
122 |
{ |
123 |
if (dis==NULL) { |
124 |
FPRINTF(stderr,"dis_set_instance called on NULL dvar\n"); |
125 |
return; |
126 |
} |
127 |
dis->datom = i; |
128 |
} |
129 |
|
130 |
|
131 |
char *dis_make_name(const slv_system_t sys,const struct dis_discrete *dis) |
132 |
{ |
133 |
return WriteInstanceNameString(IPTR(dis->datom),IPTR(slv_instance(sys))); |
134 |
} |
135 |
|
136 |
|
137 |
char *dis_make_xname(const struct dis_discrete *dis) |
138 |
{ |
139 |
static char name[81]; |
140 |
char *res; |
141 |
sprintf(name,"dis%d",dis_sindex(dis)); |
142 |
res=(char *)ascmalloc((strlen(name)+1)*sizeof(char)); |
143 |
sprintf(res,"%s",name); |
144 |
return res; |
145 |
} |
146 |
|
147 |
|
148 |
void dis_write_name(const slv_system_t sys, |
149 |
const struct dis_discrete *dis,FILE *fp) |
150 |
{ |
151 |
if (dis == NULL || fp==NULL) return; |
152 |
if (sys!=NULL) { |
153 |
WriteInstanceName(fp,dis_instance(dis),slv_instance(sys)); |
154 |
} else { |
155 |
WriteInstanceName(fp,dis_instance(dis),NULL); |
156 |
} |
157 |
} |
158 |
|
159 |
|
160 |
void dis_destroy(struct dis_discrete *dis) |
161 |
{ |
162 |
if (dis==NULL) return; |
163 |
dis->datom = NULL; |
164 |
if (dis->whens != NULL) { |
165 |
gl_destroy(dis->whens); |
166 |
dis->whens = NULL; |
167 |
} |
168 |
} |
169 |
|
170 |
|
171 |
struct gl_list_t *dis_whens_list(struct dis_discrete *dis) |
172 |
{ |
173 |
assert(dis); |
174 |
return( dis->whens ); |
175 |
} |
176 |
|
177 |
|
178 |
void dis_set_whens_list( struct dis_discrete *dis, struct gl_list_t *wlist) |
179 |
{ |
180 |
assert(dis); |
181 |
dis->whens = wlist; |
182 |
} |
183 |
|
184 |
|
185 |
enum discrete_kind dis_kindF(const struct dis_discrete *dis) |
186 |
{ |
187 |
if (dis==NULL || dis->datom==NULL) { |
188 |
FPRINTF(stderr,"dis_kind called on bad dis var\n"); |
189 |
return e_dis_error_t; |
190 |
} |
191 |
return dis->t; |
192 |
} |
193 |
|
194 |
void dis_set_kindF(struct dis_discrete *dis, enum discrete_kind kind) |
195 |
{ |
196 |
if (dis==NULL || dis->datom==NULL) { |
197 |
FPRINTF(stderr,"dis_set_kind called on bad dis var\n"); |
198 |
return; |
199 |
} |
200 |
dis->t = kind; |
201 |
} |
202 |
|
203 |
|
204 |
int32 dis_mindexF(const struct dis_discrete *dis) |
205 |
{ |
206 |
if (dis==NULL || dis->datom==NULL) { |
207 |
FPRINTF(stderr,"dis_mindex called on bad dis var\n"); |
208 |
return -1; |
209 |
} |
210 |
return dis->mindex; |
211 |
} |
212 |
|
213 |
|
214 |
void dis_set_mindexF(struct dis_discrete *dis, int32 index) |
215 |
{ |
216 |
if (dis==NULL || dis->datom==NULL) { |
217 |
FPRINTF(stderr,"dis_set_mindex called on bad dis var\n"); |
218 |
return; |
219 |
} |
220 |
dis->mindex = index; |
221 |
} |
222 |
|
223 |
int32 dis_sindexF(const struct dis_discrete *dis) |
224 |
{ |
225 |
if (dis==NULL || dis->datom==NULL) { |
226 |
FPRINTF(stderr,"dis_sindex called on bad dis var\n"); |
227 |
return -1; |
228 |
} |
229 |
return dis->sindex; |
230 |
} |
231 |
|
232 |
|
233 |
void dis_set_sindexF(struct dis_discrete *dis, int32 index) |
234 |
{ |
235 |
if (dis==NULL || dis->datom==NULL) { |
236 |
FPRINTF(stderr,"dis_set_sindex called on bad dis\n"); |
237 |
return; |
238 |
} |
239 |
dis->sindex = index; |
240 |
} |
241 |
|
242 |
|
243 |
int32 dis_value(const struct dis_discrete *dis) |
244 |
{ |
245 |
if (dis==NULL || dis->datom==NULL) { |
246 |
FPRINTF(stderr,"dis_value called on bad dis\n"); |
247 |
return 0; |
248 |
} |
249 |
return(dis->cur_value); |
250 |
} |
251 |
|
252 |
|
253 |
void dis_set_value(struct dis_discrete *dis, int32 value) |
254 |
{ |
255 |
if (dis==NULL || dis->datom==NULL) { |
256 |
FPRINTF(stderr,"dis_set_value called on bad dis\n"); |
257 |
return; |
258 |
} |
259 |
dis->pre_value = dis_value(dis); |
260 |
dis->cur_value = value; |
261 |
} |
262 |
|
263 |
|
264 |
void dis_set_inst_and_field_value(struct dis_discrete *dis, int32 value) |
265 |
{ |
266 |
if (dis==NULL || dis->datom==NULL) { |
267 |
FPRINTF(stderr,"dis_set_inst_and_field_value called on bad dis\n"); |
268 |
return; |
269 |
} |
270 |
if (dis_const(dis)) { |
271 |
return; |
272 |
} |
273 |
switch(dis->t) { |
274 |
case e_dis_boolean_t: |
275 |
dis->pre_value = dis_value(dis); |
276 |
SetBooleanAtomValue(dis->datom,value,(unsigned)0); |
277 |
dis->cur_value = GetBooleanAtomValue(dis->datom); |
278 |
break; |
279 |
case e_dis_integer_t: |
280 |
dis->pre_value = dis_value(dis); |
281 |
SetIntegerAtomValue(dis->datom,value,(unsigned)0); |
282 |
dis->cur_value = GetIntegerAtomValue(dis->datom); |
283 |
break; |
284 |
case e_dis_symbol_t: |
285 |
break; |
286 |
default: |
287 |
FPRINTF(stderr,"dis_set_inst_value called on bad dis\n"); |
288 |
return; |
289 |
} |
290 |
} |
291 |
|
292 |
|
293 |
void dis_set_value_from_inst(struct dis_discrete *dis, |
294 |
struct gl_list_t *symbol_list) |
295 |
{ |
296 |
CONST char *symval; |
297 |
|
298 |
if (dis==NULL || dis->datom==NULL) { |
299 |
FPRINTF(stderr,"dis_set_value_from_inst called on bad dis\n"); |
300 |
return; |
301 |
} |
302 |
if (dis_const(dis)) { |
303 |
return; |
304 |
} |
305 |
switch(dis->t) { |
306 |
case e_dis_boolean_t: |
307 |
dis->pre_value = dis_value(dis); |
308 |
dis->cur_value = GetBooleanAtomValue(dis->datom); |
309 |
break; |
310 |
case e_dis_integer_t: |
311 |
dis->pre_value = dis_value(dis); |
312 |
dis->cur_value = GetIntegerAtomValue(dis->datom); |
313 |
break; |
314 |
case e_dis_symbol_t: |
315 |
dis->pre_value = dis_value(dis); |
316 |
symval = SCP(GetSymbolAtomValue(dis->datom)); |
317 |
dis->cur_value = GetIntFromSymbol(symval,symbol_list); |
318 |
break; |
319 |
default: |
320 |
FPRINTF(stderr,"dis_set_value_from_inst called on bad dis\n"); |
321 |
return; |
322 |
} |
323 |
} |
324 |
|
325 |
|
326 |
int32 dis_previous_value(const struct dis_discrete *dis) |
327 |
{ |
328 |
if (dis==NULL || dis->datom==NULL) { |
329 |
FPRINTF(stderr,"dis_previous_value called on bad dis\n"); |
330 |
return 0; |
331 |
} |
332 |
return(dis->pre_value); |
333 |
} |
334 |
|
335 |
|
336 |
void dis_set_previous_value(struct dis_discrete *dis, int32 value) |
337 |
{ |
338 |
if (dis==NULL || dis->datom==NULL) { |
339 |
FPRINTF(stderr,"dis_set_previous_value called on bad dis\n"); |
340 |
return; |
341 |
} |
342 |
dis->pre_value = value; |
343 |
} |
344 |
|
345 |
|
346 |
|
347 |
static struct TypeDescription *g_solver_dis_type; |
348 |
|
349 |
boolean set_boolean_types(void) |
350 |
{ |
351 |
boolean nerr = 0; |
352 |
if( (g_solver_dis_type = FindType(AddSymbol(BOOLEAN_VAR_STR))) == NULL ) { |
353 |
FPRINTF(stderr,"ERROR: (dis.c) set_boolean_types\n"); |
354 |
FPRINTF(stderr," Type boolean_var not defined.\n"); |
355 |
nerr++; |
356 |
} |
357 |
NOMINAL_V = AddSymbolL("nominal",7); |
358 |
FIXED_V = AddSymbolL("fixed",5); |
359 |
return nerr; |
360 |
} |
361 |
|
362 |
|
363 |
boolean boolean_var( SlvBackendToken inst) |
364 |
{ |
365 |
struct TypeDescription *type; |
366 |
if (!g_solver_dis_type) return FALSE; |
367 |
type = InstanceTypeDesc(IPTR(inst)); |
368 |
return( type == MoreRefined(type,g_solver_dis_type) ); |
369 |
} |
370 |
|
371 |
|
372 |
int32 dis_nominal(struct dis_discrete *dis) |
373 |
{ |
374 |
struct Instance *c; |
375 |
if (dis==NULL || dis->datom==NULL) { |
376 |
FPRINTF(stderr,"dis_nominal called on bad dis\n"); |
377 |
return 1; |
378 |
} |
379 |
if (!boolean_var(dis->datom)) { |
380 |
FPRINTF(stderr,"dis_nominal called on a non-boolean_var\n"); |
381 |
return 1; |
382 |
} |
383 |
c = ChildByChar(dis->datom,NOMINAL_V); |
384 |
if( c == NULL ) { |
385 |
FPRINTF(stderr,"ERROR: (dis) dis_nominal\n"); |
386 |
FPRINTF(stderr," No 'nominal' field in variable.\n"); |
387 |
WriteInstance(stderr,IPTR(dis->datom)); |
388 |
return 1; |
389 |
} |
390 |
return( GetBooleanAtomValue(c) ); |
391 |
} |
392 |
|
393 |
void dis_set_nominal(struct dis_discrete *dis, int32 nominal) |
394 |
{ |
395 |
struct Instance *c; |
396 |
if (dis==NULL || dis->datom==NULL) { |
397 |
FPRINTF(stderr,"dis_set_nominal called on bad dis\n"); |
398 |
return; |
399 |
} |
400 |
if (!boolean_var(dis->datom)) { |
401 |
FPRINTF(stderr,"dis_set_nominal called on a non-boolean_var\n"); |
402 |
return; |
403 |
} |
404 |
c = ChildByChar(IPTR(dis->datom),NOMINAL_V); |
405 |
if( c == NULL ) { |
406 |
FPRINTF(stderr,"ERROR: (dis) dis_set_nominal\n"); |
407 |
FPRINTF(stderr," No 'nominal' field in variable.\n"); |
408 |
WriteInstance(stderr,IPTR(dis->datom)); |
409 |
return; |
410 |
} |
411 |
SetBooleanAtomValue(c,nominal,(unsigned)0); |
412 |
} |
413 |
|
414 |
|
415 |
uint32 dis_flagsF(const struct dis_discrete *dis) |
416 |
{ |
417 |
return dis->flags; |
418 |
} |
419 |
|
420 |
|
421 |
void dis_set_flagsF(struct dis_discrete *dis, uint32 flags) |
422 |
{ |
423 |
dis->flags = flags; |
424 |
} |
425 |
|
426 |
uint32 dis_fixed(struct dis_discrete *dis) |
427 |
{ |
428 |
struct Instance *c; |
429 |
if (dis==NULL || dis->datom==NULL) { |
430 |
FPRINTF(stderr,"dis_fixed called on bad dis\n"); |
431 |
return FALSE; |
432 |
} |
433 |
if (!boolean_var(dis->datom)) { |
434 |
if (dis_const(dis)) { |
435 |
FPRINTF(stderr,"dis_fixed called on a dis constant\n"); |
436 |
return TRUE; |
437 |
} |
438 |
else { |
439 |
FPRINTF(stderr,"dis_fixed called on a bad dis var\n"); |
440 |
return FALSE; |
441 |
} |
442 |
} |
443 |
c = ChildByChar(IPTR(dis->datom),FIXED_V); |
444 |
if( c == NULL ) { |
445 |
FPRINTF(stderr,"ERROR: (dis) dis_fixed\n"); |
446 |
FPRINTF(stderr," No 'fixed' field in variable.\n"); |
447 |
WriteInstance(stderr,IPTR(dis->datom)); |
448 |
return FALSE; |
449 |
} |
450 |
dis_set_flagbit(dis,DIS_FIXED,GetBooleanAtomValue(c)); |
451 |
return( GetBooleanAtomValue(c) ); |
452 |
} |
453 |
|
454 |
|
455 |
void dis_set_fixed(struct dis_discrete *dis, uint32 fixed) |
456 |
{ |
457 |
struct Instance *c; |
458 |
if (dis==NULL || dis->datom==NULL) { |
459 |
FPRINTF(stderr,"dis_set_fixed called on bad dis var\n"); |
460 |
return; |
461 |
} |
462 |
if (!boolean_var(dis->datom)) { |
463 |
if (dis_const(dis)) { |
464 |
FPRINTF(stderr,"dis_set_fixed called on a dis constant\n"); |
465 |
return; |
466 |
} |
467 |
else { |
468 |
FPRINTF(stderr,"dis_set_fixed called on a bad dvar\n"); |
469 |
return; |
470 |
} |
471 |
} |
472 |
c = ChildByChar(IPTR(dis->datom),FIXED_V); |
473 |
if( c == NULL ) { |
474 |
FPRINTF(stderr,"ERROR: (dis) dis_set_fixed\n"); |
475 |
FPRINTF(stderr," No 'fixed' field in variable.\n"); |
476 |
WriteInstance(stderr,IPTR(dis->datom)); |
477 |
return; |
478 |
} |
479 |
SetBooleanAtomValue(c,fixed,(unsigned)0); |
480 |
dis_set_flagbit(dis,DIS_FIXED,fixed); |
481 |
} |
482 |
|
483 |
|
484 |
extern uint32 dis_flagbit(const struct dis_discrete *dis,const uint32 one) |
485 |
{ |
486 |
if (dis==NULL || dis->datom == NULL) { |
487 |
FPRINTF(stderr,"ERROR: dis_flagbit called with bad dis.\n"); |
488 |
return 0; |
489 |
} |
490 |
return (dis->flags & one); |
491 |
} |
492 |
|
493 |
void dis_set_flagbit(struct dis_discrete *dis, uint32 field,uint32 one) |
494 |
{ |
495 |
if (dis==NULL || dis->datom == NULL) { |
496 |
FPRINTF(stderr,"ERROR: dis_set_flagbit called with bad dvar.\n"); |
497 |
return; |
498 |
} |
499 |
if (one) { |
500 |
dis->flags |= field; |
501 |
} else { |
502 |
dis->flags &= ~field; |
503 |
} |
504 |
} |
505 |
|
506 |
int32 dis_apply_filter(const struct dis_discrete *dis, |
507 |
const dis_filter_t *filter) |
508 |
{ |
509 |
if (dis==NULL || filter==NULL || dis->datom == NULL) { |
510 |
FPRINTF(stderr,"dis_apply_filter miscalled with NULL\n"); |
511 |
return FALSE; |
512 |
} |
513 |
return ( (filter->matchbits & dis->flags) == |
514 |
(filter->matchbits & filter->matchvalue) ); |
515 |
} |
516 |
|
517 |
/* global for use with the push function. Sets the ip to the |
518 |
* value in g_dis_tag; |
519 |
*/ |
520 |
static void *g_dis_tag = NULL; |
521 |
|
522 |
/* |
523 |
* should be using vp instead of a global counter. |
524 |
*/ |
525 |
static |
526 |
void *SetDisTags(struct Instance *i,VOIDPTR vp) |
527 |
{ |
528 |
(void)vp; |
529 |
if (i!=NULL && InstanceKind(i)==BOOLEAN_ATOM_INST) { |
530 |
return g_dis_tag; |
531 |
} else { |
532 |
return NULL; |
533 |
} |
534 |
} |
535 |
|
536 |
struct dis_discrete **dis_BackendTokens_to_dis(slv_system_t sys, |
537 |
SlvBackendToken *atoms, |
538 |
int32 len) |
539 |
{ |
540 |
int32 i,distot,bvlen,count=0; |
541 |
uint32 apos,ulen; |
542 |
struct dis_discrete **result; |
543 |
struct dis_discrete **dislist; |
544 |
struct gl_list_t *oldips; |
545 |
ulen = (uint32)len; |
546 |
|
547 |
if (sys==NULL || atoms == NULL || len < 1) return NULL; |
548 |
result = (struct dis_discrete **)malloc(len*sizeof(struct dis_discrete *)); |
549 |
if (result == NULL) return result; |
550 |
/* init results to null */ |
551 |
for (i=0; i<len; i++) result[i] = NULL; |
552 |
/* fill ips w/len in all the vars in tree. */ |
553 |
g_dis_tag = (void *)len; |
554 |
distot = slv_get_num_master_dvars(sys) + |
555 |
slv_get_num_master_disunatt(sys); |
556 |
oldips = PushInterfacePtrs(slv_instance(sys),SetDisTags,distot,0,NULL); |
557 |
/* fill ips of wanted atoms with i */ |
558 |
for (i=0; i<len; i++) { |
559 |
if (GetInterfacePtr(atoms[i])==g_dis_tag && |
560 |
InstanceKind(atoms[i]) == BOOLEAN_ATOM_INST) { |
561 |
/* guard a little */ |
562 |
SetInterfacePtr((struct Instance *)atoms[i],(void *)i); |
563 |
} else { |
564 |
/* |
565 |
* the odds of g_dis_tag being a legal pointer are vanishingly |
566 |
* small, so if we find an ATOM without g_dis_tag we assume it |
567 |
* is outside the tree and shouldn't have been in the list. |
568 |
*/ |
569 |
FPRINTF(stderr,"dis_BackendTokens_to_dis called with bad token.\n"); |
570 |
} |
571 |
} |
572 |
/* run through the master lists and put the dis vars with their atoms */ |
573 |
dislist = slv_get_master_dvar_list(sys); |
574 |
bvlen = slv_get_num_master_dvars(sys); |
575 |
for (i = 0; i <bvlen; i++) { |
576 |
apos = (uint32)GetInterfacePtr(dis_instance(dislist[i])); |
577 |
if ( apos < ulen ) { |
578 |
result[apos] = dislist[i]; |
579 |
count++; |
580 |
} |
581 |
} |
582 |
dislist = slv_get_master_disunatt_list(sys); |
583 |
bvlen = slv_get_num_master_disunatt(sys); |
584 |
for (i = 0; i <bvlen; i++) { |
585 |
apos = (uint32)GetInterfacePtr(dis_instance(dislist[i])); |
586 |
if ( apos < ulen ) { |
587 |
result[apos] = dislist[i]; |
588 |
count++; |
589 |
} |
590 |
} |
591 |
if (count < len) { |
592 |
FPRINTF(stderr, |
593 |
"dis_BackendTokens_to_dis found less than expected dis vars\n"); |
594 |
FPRINTF(stderr,"len = %d, diss found = %d\n",len,count); |
595 |
} else { |
596 |
FPRINTF(stderr, |
597 |
"dis_BackendTokens_to_dis found more than expected dis vars\n"); |
598 |
FPRINTF(stderr,"len = %d, diss found = %d\n",len,count); |
599 |
} |
600 |
PopInterfacePtrs(oldips,NULL,NULL); |
601 |
return result; |
602 |
} |
603 |
|