/[ascend]/trunk/tcltk/generic/interface/UnitsProc.c
ViewVC logotype

Contents of /trunk/tcltk/generic/interface/UnitsProc.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 912 - (show annotations) (download) (as text)
Fri Oct 27 07:18:21 2006 UTC (17 years, 11 months ago) by johnpye
File MIME type: text/x-csrc
File size: 62378 byte(s)
Removed BBOXWHINE (replaced with some one-time-only warnings for the moment)
Added ExtMethodDestroyFn to allow 'user_data' associated with external methods to be destroyed.
Implemented the destroy fn through to 'extpy' module.
Added 'name' as an extra parameter in the user_data for extpy, to help with debug msgs.
Moved 'solvernotes' to a file of its own (was part of listnotes.py)
Added 'repaint' to GTK 'tools' menu (for debugging)
Added 'python.h' to top of library, type files (pygtk) to stop silly warnings.
Working on some diagnosing of problems as noted in Simulation::checkInstance.
Removed some old comments from namio.h and others.
Renamed 'blsys' to 'sys' in integrator.c.
Some work on fixing up the J*v function for IDA (not yet complete).
Added new 'destroyfn' parameter (as NULL) to all calls to 'CreateUserFunctionMethod'.
1 /*
2 * UnitsProc.c
3 * by Kirk Abbott and Ben Allan
4 * Created: 1/94
5 * Version: $Revision: 1.41 $
6 * Version control file: $RCSfile: UnitsProc.c,v $
7 * Date last modified: $Date: 2003/08/23 18:43:08 $
8 * Last modified by: $Author: ballan $
9 *
10 * This file is part of the ASCEND Tcl/Tk interface
11 *
12 * Copyright 1997, Carnegie Mellon University
13 *
14 * The ASCEND Tcl/Tk interface is free software; you can redistribute
15 * it and/or modify it under the terms of the GNU General Public License as
16 * published by the Free Software Foundation; either version 2 of the
17 * License, or (at your option) any later version.
18 *
19 * The ASCEND Tcl/Tk interface is distributed in hope that it will be
20 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 * General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with the program; if not, write to the Free Software Foundation,
26 * Inc., 675 Mass Ave, Cambridge, MA 02139 USA. Check the file named
27 * COPYING. COPYING is found in ../compiler.
28 */
29
30 #define ASC_BUILDING_INTERFACE
31
32 #ifndef NO_SIGNAL_TRAPS
33 # include <signal.h>
34 # include <setjmp.h>
35 #endif
36
37 #include <stdarg.h>
38 #include <tcl.h>
39 #include <utilities/ascConfig.h>
40 #include <utilities/ascSignal.h>
41 #include <utilities/ascMalloc.h>
42 #include <utilities/ascPanic.h>
43 #include <general/list.h>
44 #include <general/dstring.h>
45 #include <compiler/compiler.h>
46 #include <compiler/instance_enum.h>
47 #include <compiler/cmpfunc.h>
48 #include <compiler/fractions.h>
49 #include <compiler/dimen.h>
50 #include <compiler/dimen_io.h>
51 #include <compiler/units.h>
52 #include <compiler/child.h>
53 #include <compiler/type_desc.h>
54 #include <compiler/module.h>
55 #include <compiler/library.h>
56 #include <compiler/symtab.h>
57 #include <compiler/instance_io.h>
58 #include <compiler/atomvalue.h>
59 #include <compiler/instquery.h>
60 #include <compiler/expr_types.h>
61 #include <compiler/mathinst.h>
62 #include <compiler/instance_name.h>
63 #include <compiler/relation_type.h>
64 #include <compiler/extfunc.h>
65 #include <compiler/find.h>
66 #include <compiler/rel_blackbox.h>
67 #include <compiler/vlist.h>
68 #include <compiler/relation.h>
69 #include <compiler/functype.h>
70 #include <compiler/safe.h>
71 #include <compiler/relation_util.h>
72 #include <solver/slv_types.h>
73 #include <solver/var.h>
74 #include <solver/rel.h>
75 #include <solver/discrete.h>
76 #include <solver/conditional.h>
77 #include <solver/logrel.h>
78 #include <solver/bnd.h>
79 #include <solver/mtx.h>
80 #include <solver/slv_common.h>
81 #include <solver/linsol.h>
82 #include <solver/linsolqr.h>
83 #include <solver/slv_client.h>
84 #include "old_utils.h"
85 #include "HelpProc.h"
86 #include "UnitsProc.h"
87 #include "BrowserQuery.h"
88 #include "BrowserProc.h"
89 #include "Qlfdid.h"
90 #include "Driver.h"
91 #include "HelpProc.h"
92 #include "SolverGlobals.h"
93
94 #ifndef lint
95 static CONST char UnitsProcID[] = "$Id: UnitsProc.c,v 1.41 2003/08/23 18:43:08 ballan Exp $";
96 #endif
97
98
99 /* convenience macros */
100 #define SNULL (char *)NULL
101 #define UnitsFindType(s) FindType(AddSymbol(s))
102
103 /* return info when units convert badly. because io may happen within
104 * another trap context, we have our own return address and return function.
105 */
106 static jmp_buf g_unit_env;
107
108 struct Units * g_base_units[NUM_DIMENS];
109 struct Units * g_SI_units[NUM_DIMENS];
110
111 /*********************INTERNALS ******************************/
112
113 static int display_precision = 6;
114 static char *unit_display_string = NULL;
115 static int updatefundunitdim;
116 static Tcl_Interp *unitsinterp;
117 #define UDS (unit_display_string)
118 #define UPREC (display_precision)
119
120 #define DLSIZE (512L)
121 /* while there are infinitely many instances and units combos, there are
122 only a limited (in practice) number of dimensionalities. DLSIZE should
123 be a reasonable upper bound on that limited number.
124 */
125 static struct gl_list_t *DUList; /* association list for display units */
126
127 struct DisplayUnit {
128 dim_type *d; /* dimensionality applied to */
129 struct Units *u; /* user set display units */
130 struct Units *fu; /* fundamental display units */
131 };
132
133
134 static int check_units_set(ClientData cdata, Tcl_Interp *interp,
135 int argc, CONST84 char *argv[]) /* args ignored but needed*/
136 {
137 static int base_units_set;
138 if (!base_units_set) {
139 Asc_UnitDefaultBaseUnits(cdata,interp,argc,argv);
140 base_units_set = 1;
141 }
142 return (base_units_set);
143 }
144
145 static
146 int Unit_CmpDU(CONST struct DisplayUnit *du1, CONST struct DisplayUnit *du2)
147 {
148 return CmpDimen(du1->d,du2->d);
149 }
150
151 static int destroy_DUList() {
152 if (DUList) {
153 gl_free_and_destroy(DUList);
154 }
155 return 0;
156 }
157
158 static int check_DU_set()
159 {
160 static int duset = 0 ;
161 if (!duset) { /* first time through, init the world */
162 dim_type *d;
163 register unsigned long c,len = gl_length(g_dimen_list);
164 struct DisplayUnit *newDU;
165 DUList = gl_create(DLSIZE);
166 assert(DUList!=NULL);
167 for(c = 1;c <= len;c++) { /*far faster than FindOrAddDU */
168 newDU=(struct DisplayUnit *)ascmalloc(sizeof(struct DisplayUnit));
169 d = (dim_type *)gl_fetch(g_dimen_list,c);
170 newDU->d = d;
171 newDU->u = (struct Units *)NULL;
172 newDU->fu = (struct Units *)NULL;
173 gl_insert_sorted(DUList,(VOIDPTR)newDU,(CmpFunc)Unit_CmpDU);
174 }
175 duset = 1;
176 }
177 return (duset);
178 }
179
180 /* push fundy's to bottom of list */
181 static
182 int Unit_CmpAtomName(CONST struct TypeDescription *d1,
183 CONST struct TypeDescription *d2)
184 {
185 if (!d1 || !d2 || CheckFundamental(GetName(d1)) ) {
186 return 1;
187 }
188 return CmpSymchar(GetName(d1),GetName(d2));
189 }
190
191 /* small numbers and nulls go to the bottom (high index) of the list */
192 static
193 int Unit_CmpConv(CONST struct Units *u1, CONST struct Units *u2)
194 {
195 if (!u1 || !u2 || UnitsConvFactor(u1)<UnitsConvFactor(u2)) {
196 return 1;
197 }
198 if (UnitsConvFactor(u1)==UnitsConvFactor(u2)) {
199 if (SCLEN(UnitsDescription(u1)) > SCLEN(UnitsDescription(u2))) {
200 return 1;
201 } else if (SCLEN(UnitsDescription(u1)) < SCLEN(UnitsDescription(u2))) {
202 return -1;
203 } else {
204 return (CmpSymchar(UnitsDescription(u1),UnitsDescription(u2)));
205 }
206 } else {
207 return -1;
208 }
209 }
210
211 /*
212 * note that since fractional and irrational exponents are not allowed
213 * on dimensioned quantities, we don't have to worry on denominator.
214 */
215 static
216 void Unit_WriteNumer(Tcl_DString *str, struct fraction frac,
217 CONST char *baseunit, int *CONST p)
218 {
219 char sval[MAXIMUM_NUMERIC_LENGTH];
220 if (Numerator(frac)>0) {
221 (*p) = 1;
222 if (Denominator(frac)==1) {
223 if (Numerator(frac)==1) {
224 sprintf(sval,"%s*",baseunit);
225 } else {
226 sprintf(sval,"%s^%d*",baseunit,Numerator(frac));
227 }
228 } else {
229 /* this won't parse, but shouldn't happen anyway */
230 sprintf(sval,"%s^(%d/%d)*",baseunit,Numerator(frac),Denominator(frac));
231 }
232 Tcl_DStringAppend(str,sval,-1);
233 }
234 }
235
236 static
237 void Unit_WriteDenom(Tcl_DString *str, struct fraction frac,
238 CONST char *baseunit, int *CONST p)
239 {
240 char sval[MAXIMUM_NUMERIC_LENGTH];
241 if (Numerator(frac)<0) {
242 (*p) = 1;
243 if (Denominator(frac)==1) {
244 if (Numerator(frac)==-1) {
245 sprintf(sval,"/%s",baseunit);
246 } else {
247 sprintf(sval,"/%s^%d",baseunit,-Numerator(frac));
248 }
249 } else {
250 /* this won't parse, but shouldn't happen anyway */
251 sprintf(sval,"/%s^(%d/%d)",baseunit,-Numerator(frac),Denominator(frac));
252 }
253 Tcl_DStringAppend(str,sval,-1);
254 }
255 }
256
257 /* return a nicely formatted units string */
258 static
259 char *Unit_MakeString(const dim_type *dimp, struct Units * units[NUM_DIMENS])
260 {
261 struct fraction frac;
262 Tcl_DString str1, str2;
263 char *result;
264 int printed = 0,len;
265 Tcl_DStringInit(&str1);
266 Tcl_DStringInit(&str2);
267 if (IsWild(dimp)) {
268 Tcl_DStringAppend(&str2,"*",-1);
269 } else {
270 int i;
271 for( i = 0; i<NUM_DIMENS; i++ ) {
272 frac = GetDimFraction(*dimp,i);
273 Unit_WriteNumer(&str1,frac,SCP(UnitsDescription(units[i])),&printed);
274 }
275 if (!printed) {
276 Tcl_DStringAppend(&str2,"1",-1);
277 printed = 1;
278 } else {
279 /* eat the trailing multiply */
280 Tcl_DStringAppend(&str2,
281 Tcl_DStringValue(&str1),
282 (strlen(Tcl_DStringValue(&str1))-1) );
283 }
284 for( i = 0; i<NUM_DIMENS; i++ ) {
285 frac = GetDimFraction(*dimp,i);
286 Unit_WriteDenom(&str2,frac,SCP(UnitsDescription(units[i])),&printed);
287 }
288 }
289 len = strlen(Tcl_DStringValue(&str2));
290 result = Asc_MakeInitString(len);
291 strcpy(result, Tcl_DStringValue(&str2));
292 Tcl_DStringFree(&str1);
293 Tcl_DStringFree(&str2);
294 return result;
295 }
296
297 #ifdef THIS_IS_AN_UNUSED_FUNCTION
298 static
299 void Unit_PrintDU(struct DisplayUnit *du)
300 {
301 if (du==NULL) {
302 FPRINTF(stderr,"NULL");
303 } else {
304 FPRINTF(stderr,"0x%p 0x%p \n",du->d, du->u);
305 }
306 }
307 #endif /* THIS_IS_AN_UNUSED_FUNCTION */
308
309 /*
310 * return the DisplayUnit pointer that matches dimp.
311 * create it if necessary. failing create, crash.
312 */
313 static struct DisplayUnit *Unit_FindOrAddDU(const dim_type *dimp)
314 {
315 unsigned long ndx;
316 struct DisplayUnit dimpDU;
317 struct DisplayUnit *newdu;
318
319 dimpDU.d = (dim_type *)dimp;
320 check_DU_set();
321 ndx = gl_search(DUList,(VOIDPTR)&dimpDU,(CmpFunc)Unit_CmpDU);
322 if (ndx==0L) {
323 newdu = ASC_NEW(struct DisplayUnit);
324 newdu->d = (dim_type *)dimp;
325 newdu->u = NULL;
326 newdu->fu = NULL;
327 gl_insert_sorted(DUList,(VOIDPTR)newdu,(CmpFunc)Unit_CmpDU);
328 return newdu;
329 }
330 return ((struct DisplayUnit *)gl_fetch(DUList,ndx));
331 }
332
333 /*
334 * returns display unit matching dimp, creating it in association list if
335 * not existing. Will not actually create a Units struct. a NULL return
336 * means the unit has been defaulted in the units window.
337 */
338 static struct Units *Unit_DisplayUnits(const dim_type *dimp)
339 {
340 struct DisplayUnit *dimpdu;
341 assert(check_DU_set());
342 dimpdu = Unit_FindOrAddDU(dimp);
343 return (dimpdu->u);
344 }
345
346 /*
347 * called when display unit is defaulted. constructs a display string
348 * if needed using user set base units and adds to the Units hash table.
349 * returns the pointer of the fund units.
350 */
351 static struct Units *Unit_DisplayFund(const dim_type *dimp)
352 {
353 struct DisplayUnit* dimpDU;
354 char *newunits = NULL;
355 unsigned long pos;
356 int ecode;
357
358 assert(check_DU_set());
359 dimpDU = Unit_FindOrAddDU(dimp);
360 if (dimpDU->fu==NULL) {
361 newunits = Unit_MakeString(dimp,g_base_units);
362 dimpDU->fu = (struct Units *)FindOrDefineUnits(newunits,&pos,&ecode);
363 if (!dimpDU->fu) {
364 FPRINTF(stderr,"Error %d, position %ld\n",ecode,pos);
365 FPRINTF(stderr,"failed fundstring: {%s} \n",newunits);
366 }
367 if (newunits) {
368 ascfree(newunits);
369 }
370 }
371 return (dimpDU->fu);
372 }
373
374 /*
375 * called when display unit is too small. constructs a display string
376 * using SI base units and adds to the Units hash table if needed.
377 * returns the pointer of the units. This should seldom be called, so
378 * we are constructing the string every time rather than expanding
379 * the DisplayUnit struct.
380 */
381 static struct Units *Unit_DisplaySI(const dim_type *dimp)
382 {
383 static unsigned long pos;
384 static int ecode;
385 struct Units *u;
386 char *newunits = Unit_MakeString(dimp,g_SI_units);
387 u = (struct Units *)FindOrDefineUnits(newunits,&pos,&ecode);
388 if (!u) {
389 FPRINTF(stderr,"error %d, position %ld\n",ecode,pos);
390 FPRINTF(stderr,"SIstring: {%s} \n",newunits);
391 }
392 if (newunits) {
393 ascfree(newunits);
394 }
395 return u;
396 }
397
398 /*
399 * this function checks to see if the fundamental unit being updated
400 * needs to be changed in already set displayunits.
401 */
402 static
403 void Unit_UpdateFundUnits(struct DisplayUnit *du)
404 {
405 dim_type *d;
406
407 if (du==NULL || du->fu==NULL) {
408 return;
409 }
410 d = (dim_type *)UnitsDimensions(du->fu);
411 if (Numerator(GetDimFraction(*(dim_type *)UnitsDimensions(du->fu),
412 updatefundunitdim)) != 0) {
413 du->fu = NULL;
414 Unit_DisplayFund(du->d);
415 }
416 }
417
418 #ifndef NO_SIGNAL_TRAPS
419 /* un/conversion error handling done in the next 5 procedures */
420 static
421 void uunconversion_trap(int sigval)
422 {
423 (void)sigval; /* stop gcc whine about unused parameter */
424
425 FPRINTF(stderr,"Float error in converting display value to SI value.\n");
426 FPRESET;
427 longjmp(g_unit_env,SIGFPE);
428 }
429 #endif /* NO_SIGNAL_TRAPS */
430
431 /* respects any already active Asc_SignalTrap as we may want unit
432 * output during another call which needs trapping.
433 * retval is the SI value converted from the units specified by u
434 * returns 1 if unhappy, 0 otherwise.
435 */
436 static int Unit_UnconvertReal(double val, struct Units *u, double *retval)
437 {
438 static int status;
439 if (!u) {
440 return 1;
441 }
442 #ifndef NO_SIGNAL_TRAPS
443 Asc_SignalHandlerPush(SIGFPE,uunconversion_trap);
444 if (setjmp(g_unit_env)==0) {
445 #endif /* NO_SIGNAL_TRAPS */
446 status = 0;
447 *retval = val*UnitsConvFactor(u);
448 #ifndef NO_SIGNAL_TRAPS
449 } else {
450 status = 1;
451 }
452 Asc_SignalHandlerPop(SIGFPE,uunconversion_trap);
453 #endif /* NO_SIGNAL_TRAPS */
454 return status;
455 }
456
457 static
458 void uconversion_trap(int sigval)
459 {
460 (void)sigval; /* stop gcc whine about unused parameter */
461
462 FPRINTF(stderr,"Float error in converting SI value to display units.\n");
463 FPRESET;
464 longjmp(g_unit_env,SIGFPE);
465 }
466
467 /* respects any already active fp_trap
468 * retval is the display value in the units specified by u
469 */
470 static int Unit_ConvertReal(double val, struct Units *u, double *retval)
471 {
472 static int status;
473 if (!u) {
474 return 1;
475 }
476 #ifndef NO_SIGNAL_TRAPS
477 Asc_SignalHandlerPush(SIGFPE,uconversion_trap);
478 if (setjmp(g_unit_env)==0) {
479 #endif /* NO_SIGNAL_TRAPS */
480 status = 0;
481 /* often enough debug
482 FPRINTF(stderr,"Conversion: v%.16g f%.16g\n",val,UnitsConvFactor(u));
483 */
484 *retval = val/UnitsConvFactor(u);
485 #ifndef NO_SIGNAL_TRAPS
486 } else {
487 status = 1;
488 }
489 Asc_SignalHandlerPop(SIGFPE,uconversion_trap);
490 #endif /* NO_SIGNAL_TRAPS */
491 return status;
492 }
493
494 /* does integer math yield errors?? */
495 static int Unit_ConvertInteger(long val, struct Units *u, long *retval)
496 {
497 (void)u; /* stop gcc whine about unused parameter */
498
499 *retval = val;
500 return 0;
501 }
502 /* end any pretense of conversion error handling */
503
504 static int Unit_PrintUndefined(dim_type *dimp)
505 {
506 char str[MAXIMUM_NUMERIC_LENGTH];
507 int len;
508 struct Units *du;
509 if (IsWild(dimp)) {
510 sprintf(str,"UNDEFINED *");
511 len = 11; /* should match prior sprintf */
512 UDS = Asc_MakeInitString(len);
513 strcat(UDS,str);
514 return 0;
515 }
516 if (CmpDimen(dimp,Dimensionless())==0) {
517 sprintf(str,"UNDEFINED ");
518 len = 10;
519 UDS = Asc_MakeInitString(len);
520 strcat(UDS,str);
521 return 0;
522 }
523 du = Unit_DisplayUnits(dimp); /* get units window set */
524 if (du==NULL) { /* if defaulted, use base units */
525 du = Unit_DisplayFund(dimp);
526 }
527 assert(du!=NULL);
528 sprintf(str,"UNDEFINED ");
529 len = strlen(str)+SCLEN(UnitsDescription(du));
530 UDS = Asc_MakeInitString(len);
531 strcat(UDS,str);
532 strcat(UDS,SCP(UnitsDescription(du)));
533 return 0;
534 }
535
536 static int Unitless_PrintUndefined(void)
537 {
538 UDS = Asc_MakeInitString(9);
539 strcat(UDS,"UNDEFINED");
540 return 0;
541 }
542
543 /*
544 * Assumes UDS is NULL on entry. That's why it's static.
545 * Unit_PrintXXXXX are responsible for mallocing UDS, and
546 * Asc_UnitValue is responsible for destroying it.
547 */
548 static int Unit_PrintReal(double val, dim_type *dimp)
549 {
550 char str[MAXIMUM_NUMERIC_LENGTH];
551 int len;
552 double dval; /* the printed value */
553 struct Units *du;
554 if (IsWild(dimp)) {
555 sprintf(str,"%.*g *",UPREC,val);
556 len = strlen(str);
557 UDS = Asc_MakeInitString(len);
558 strcat(UDS,str);
559 return 0;
560 }
561 if (CmpDimen(dimp,Dimensionless())==0) {
562 sprintf(str,"%.*g",UPREC,val);
563 len = strlen(str);
564 UDS = Asc_MakeInitString(len);
565 strcat(UDS,str);
566 return 0;
567 }
568 du = Unit_DisplayUnits(dimp); /* get units window set */
569 if (du==NULL) { /* if defaulted, use base units */
570 du = Unit_DisplayFund(dimp);
571 if (Unit_ConvertReal(val,du,&dval)) { /* if conversion error, use SI */
572 du = Unit_DisplaySI(dimp);
573 dval = val;
574 }
575 } else {
576 if (Unit_ConvertReal(val,du,&dval)) { /* if units window set failed */
577 du = Unit_DisplayFund(dimp); /* get base units */
578 if (Unit_ConvertReal(val,du,&dval)) {/* if conversion error, use SI */
579 du = Unit_DisplaySI(dimp);
580 dval = val;
581 }
582 }
583 }
584 assert(du!=NULL);
585 sprintf(str,"%.*g ",UPREC,dval);
586 len = strlen(str)+SCLEN(UnitsDescription(du));
587 UDS = Asc_MakeInitString(len);
588 strcat(UDS,str);
589 strcat(UDS,SCP(UnitsDescription(du)));
590 return 0;
591 }
592
593 /*
594 * Assumes UDS is NULL on entry. That's why it's static.
595 * Call only from Asc_UnitValue.
596 */
597 static int Unitless_PrintReal(double val, dim_type *dimp, int si)
598 {
599 char str[MAXIMUM_NUMERIC_LENGTH];
600 int len;
601 double dval; /* the printed value */
602 struct Units *du;
603 if (IsWild(dimp) || CmpDimen(dimp,Dimensionless())==0) {
604 sprintf(str,"%.*g",UPREC,val);
605 len = strlen(str);
606 UDS = Asc_MakeInitString(len);
607 strcat(UDS,str);
608 return 0;
609 }
610 du = Unit_DisplayUnits(dimp); /* get units window set */
611 if (du==NULL) { /* if defaulted, use base units */
612 du = Unit_DisplayFund(dimp);
613 if (si || Unit_ConvertReal(val,du,&dval)) {
614 /* if conversion error or si, use SI */
615 dval = val;
616 }
617 } else {
618 if (si || Unit_ConvertReal(val,du,&dval)) {
619 /* if si or units window set conversion failed */
620 du = Unit_DisplayFund(dimp); /* get base units */
621 if (si || Unit_ConvertReal(val,du,&dval)) {
622 /* if conversion error or si, use SI */
623 dval = val;
624 }
625 }
626 }
627 sprintf(str,"%.*g",UPREC,dval);
628 len = strlen(str);
629 UDS = Asc_MakeInitString(len);
630 strcat(UDS,str);
631 return 0;
632 }
633
634 /*
635 * Assumes UDS is NULL on entry. That's why it's static.
636 * Call only from Asc_UnitValue.
637 */
638 static int Unit_PrintInteger(long val, dim_type *dimp)
639 {
640 char str[81];
641 int len;
642 long dval; /* the printed value */
643 struct Units *du;
644 if (CmpDimen(dimp,Dimensionless())==0) {
645 sprintf(str,"%ld",val);
646 len = strlen(str);
647 UDS = Asc_MakeInitString(len);
648 strcat(UDS,str);
649 return 0;
650 }
651 if (IsWild(dimp)) {
652 sprintf(str,"%ld *",val);
653 len = strlen(str);
654 UDS = Asc_MakeInitString(len);
655 strcat(UDS,str);
656 return 0;
657 }
658 du = Unit_DisplayUnits(dimp); /* get units window set */
659 if (du==NULL) { /* if defaulted, use base units */
660 du = Unit_DisplayFund(dimp);
661 if (Unit_ConvertInteger(val,du,&dval)) { /* if conversion error, use SI */
662 du = Unit_DisplaySI(dimp);
663 dval = val;
664 }
665 } else {
666 if (Unit_ConvertInteger(val,du,&dval)) { /* if units window set failed */
667 du = Unit_DisplayFund(dimp); /* get base units */
668 if (Unit_ConvertInteger(val,du,&dval)) {/* if conversion error, use SI */
669 du = Unit_DisplaySI(dimp);
670 dval = val;
671 }
672 }
673 }
674 sprintf(str,"%ld ",dval);
675 len = strlen(str)+SCLEN(UnitsDescription(du));
676 UDS = Asc_MakeInitString(len);
677 strcat(UDS,str);
678 strcat(UDS,SCP(UnitsDescription(du)));
679 return 0;
680 }
681
682 /*
683 * This code at the moment is only valid for token relations.
684 */
685 static
686 dim_type *Unit_FindRelDim(CONST struct Instance *i)
687 {
688 int consistent;
689 dim_type dim;
690 dim_type *newd;
691 CONST struct relation *reln;
692 enum Expr_enum reltype;
693
694 reln = GetInstanceRelation(i,&reltype);
695 switch (reltype) {
696 case e_blackbox:
697 if (!IsWild(RelationDim(reln))) {
698 return RelationDim(reln);
699 }
700 if (g_check_dimensions_noisy) {
701 ERROR_REPORTER_HERE(ASC_PROG_WARNING,"Blackbox relation dimensionality waiting on output var dimensionality.");
702 /* should come off lhs var of blackbox */
703 }
704 return (dim_type *)WildDimension();
705 case e_glassbox:
706 case e_opcode:
707 if (g_check_dimensions_noisy) {
708 ERROR_REPORTER_HERE(ASC_PROG_ERR,"Dimensionality checking not supported for these relns");
709 }
710 return (dim_type *)WildDimension();
711 case e_token:
712 break;
713 default:
714 Asc_Panic(2, __FUNCTION__, "Type is not a relation type in Unit_FindRelDimen.");
715 }
716
717 consistent = asc_check_dimensions(reln,&dim);
718 if( !consistent ) {
719 if (g_check_dimensions_noisy) {
720 FPRINTF(stderr,"An inconsistency was found in ");
721 WriteInstanceName(stderr,i,NULL); PRINTF("\n");
722 }
723 return (dim_type *)WildDimension();
724 } else {
725 newd = (dim_type *)FindOrAddDimen(&dim);
726 if (consistent ==1) {
727 SetRelationDim((struct relation *)reln,newd);
728 }
729 return newd;
730 }
731 }
732
733 /*
734 * returns TRUE if the instance is NULL or is dimensionally
735 * sane. integers are sane (DIMENSIONLESS).
736 */
737 static int IsDimInstance(CONST struct Instance *i)
738 {
739 enum inst_t t;
740 if (!i) {
741 return 1;
742 }
743 t = InstanceKind(i);
744 return (t== REAL_ATOM_INST || /* non-fundamental real atom */
745 t==REAL_INST || /* a fundamental real instance */
746 t==REAL_CONSTANT_INST || /* a non fundamental real
747 * constant instance */
748 t==INTEGER_ATOM_INST || /* non-fundamental integer atom */
749 t==INTEGER_INST || /* a fundamental integer instance */
750 t==INTEGER_CONSTANT_INST || /* a non fundamental integer
751 * constant instance */
752 t==REL_INST /* relation(equality or inequality) */
753 );
754 }
755
756 /*
757 * Don't call it on a non-dimensional instance or you will get what
758 * you deserve: a null pointer back.
759 * For my purposes dimensional instances are INT, REAL, REL and their
760 * ATOM versions.
761 * Happens to not mind integers,since I think integers will have dims
762 * eventually, and because it make the browser easy to deal with.
763 * This is the broker for access to the Unit_PrintXXXXX routines and
764 * is responsible for destroying the UDS.
765 */
766 char *Asc_UnitValue(CONST struct Instance *i)
767 {
768 double dval;
769 dim_type *dimp = NULL;
770 long ival;
771 CONST struct relation *reln;
772 enum Expr_enum reltype;
773
774 if (UDS) {
775 ascfree(UDS);
776 UDS = SNULL;
777 }
778 if (!i) {
779 return SNULL;
780 }
781 switch (InstanceKind(i)) {
782 case REAL_ATOM_INST:
783 case REAL_CONSTANT_INST:
784 case REAL_INST:
785 dimp = (dim_type *)RealAtomDims(i);
786 if (!AtomAssigned(i)) {
787 Unit_PrintUndefined(dimp);
788 } else {
789 dval = RealAtomValue(i);
790 Unit_PrintReal(dval,dimp);
791 }
792 break;
793 case REL_INST:
794 reln = GetInstanceRelation(i,&reltype);
795 if (reln!=NULL) {
796 dval = RelationResidual((struct relation *)reln);
797 dimp = Unit_FindRelDim(i);
798 } else {
799 dval = 0.0;
800 dimp = (dim_type *)WildDimension();
801 }
802 Unit_PrintReal(dval,dimp);
803 break;
804 case INTEGER_INST:
805 case INTEGER_CONSTANT_INST:
806 case INTEGER_ATOM_INST:
807 /* dimp = IntegerAtomDims(i); Doesnotexist. integer inst don't have dim.*/
808 if (!AtomAssigned(i)) {
809 Unit_PrintUndefined((dim_type *)Dimensionless());
810 } else {
811 ival = GetIntegerAtomValue(i);
812 Unit_PrintInteger(ival,(dim_type *)Dimensionless());
813 }
814 break;
815 default:
816 break;
817 }
818 return UDS;
819 }
820
821 /* follows exactly the same UDS management protocol as Asc_UnitValue. see
822 comments above */
823 char *Asc_UnitlessValue(CONST struct Instance *i, int si)
824 {
825 double dval;
826 dim_type *dimp = NULL;
827 long ival;
828 enum Expr_enum reltype;
829 if (UDS) {
830 ascfree(UDS);
831 UDS = SNULL;
832 }
833 if (!i) {
834 return SNULL;
835 }
836 switch (InstanceKind(i)) {
837 case REAL_ATOM_INST:
838 case REAL_CONSTANT_INST:
839 case REAL_INST:
840 dimp = (dim_type *)RealAtomDims(i);
841 if (!AtomAssigned(i)) {
842 Unitless_PrintUndefined();
843 } else {
844 dval = RealAtomValue(i);
845 Unitless_PrintReal(dval,dimp,si);
846 }
847 break;
848 case REL_INST:
849 if (GetInstanceRelation(i,&reltype)!=NULL) {
850 dval = RelationResidual(GetInstanceRelation(i,&reltype));
851 dimp = Unit_FindRelDim(i);
852 } else {
853 dval = 0.0;
854 dimp = (dim_type *)WildDimension();
855 }
856 Unitless_PrintReal(dval,dimp,si);
857 break;
858 case INTEGER_INST:
859 case INTEGER_CONSTANT_INST:
860 case INTEGER_ATOM_INST:
861 /* dimp = IntegerAtomDims(i); Doesnotexist. integer inst don't have dim.*/
862 if (!AtomAssigned(i)) {
863 Unit_PrintUndefined((dim_type *)Dimensionless());
864 } else {
865 ival = GetIntegerAtomValue(i);
866 Unit_PrintInteger(ival,(dim_type *)Dimensionless());
867 }
868 break;
869 default:
870 break;
871 }
872 return UDS;
873 }
874 /* follows UDS string convention as for Asc_UnitValue. */
875 char *Asc_UnitString(CONST struct Instance *i, int si)
876 {
877 dim_type *dimp = NULL;
878 struct Units *du;
879 size_t len;
880 enum Expr_enum reltype;
881 if (UDS) {
882 ascfree(UDS);
883 UDS = SNULL;
884 }
885 if (!i) {
886 return SNULL;
887 }
888 switch (InstanceKind(i)) {
889 case REAL_ATOM_INST:
890 case REAL_CONSTANT_INST:
891 case REAL_INST:
892 dimp = (dim_type *)RealAtomDims(i);
893 break;
894 case REL_INST:
895 if (GetInstanceRelation(i,&reltype)!=NULL) {
896 dimp = Unit_FindRelDim(i);
897 } else {
898 dimp = (dim_type *)WildDimension();
899 }
900 break;
901 case INTEGER_INST:
902 case INTEGER_CONSTANT_INST:
903 case INTEGER_ATOM_INST:
904 dimp = (dim_type *)Dimensionless();
905 break;
906 default:
907 break;
908 }
909 if (dimp == NULL) {
910 FPRINTF(stderr,
911 "WARNING: (Asc_UnitString) Called on undimensional instance\n");
912 return UDS;
913 }
914 if (IsWild(dimp)) {
915 UDS = Asc_MakeInitString(1);
916 strcat(UDS,"*");
917 return UDS;
918 }
919 if (CmpDimen(dimp,Dimensionless())==0) {
920 UDS = Asc_MakeInitString(1);
921 sprintf(UDS,"%s","");
922 return UDS;
923 }
924 if (si) {
925 du = Unit_DisplaySI(dimp);
926 } else {
927 du = Unit_DisplayUnits(dimp); /* get units window set */
928 if (du==NULL) { /* if defaulted, use base units */
929 du = Unit_DisplayFund(dimp);
930 }
931 }
932 len = SCLEN(UnitsDescription(du));
933 UDS = Asc_MakeInitString(len);
934 strcat(UDS,SCP(UnitsDescription(du)));
935 return UDS;
936 }
937
938 /* follows UDS string convention as for Asc_UnitValue. */
939 char *Asc_UnitDimString(const dim_type *dimp, int si)
940 {
941 struct Units *du;
942 size_t len;
943 if (UDS) {
944 ascfree(UDS);
945 UDS = SNULL;
946 }
947 if (dimp==NULL) {
948 return SNULL;
949 }
950 if (IsWild(dimp)) {
951 UDS = Asc_MakeInitString(1);
952 strcat(UDS,"*");
953 return UDS;
954 }
955 if (CmpDimen(dimp,Dimensionless())==0) {
956 UDS = Asc_MakeInitString(1);
957 sprintf(UDS,"%s","");
958 return UDS;
959 }
960 if (si) {
961 du = Unit_DisplaySI(dimp);
962 } else {
963 du = Unit_DisplayUnits(dimp); /* get units window set */
964 if (du==NULL) { /* if defaulted, use base units */
965 du = Unit_DisplayFund(dimp);
966 }
967 }
968 len = SCLEN(UnitsDescription(du));
969 UDS = Asc_MakeInitString(len);
970 strcat(UDS,SCP(UnitsDescription(du)));
971 return UDS;
972 }
973
974 /* Convert to/from si. if si is TRUE, assumes in is si value and
975 tries to convert value consistent with units given. If si is FALSE
976 assumes in is value in units given and tries to convert to si.
977 */
978 int Asc_UnitConvert(struct Units *u, double in, double *op, int si)
979 {
980
981 if (u==NULL || op == NULL) {
982 return 1;
983 }
984 if (si) {
985 if (Unit_ConvertReal(in,u,op)) {
986 return 1;
987 } else {
988 return 0;
989 }
990 } else {
991 if (Unit_UnconvertReal(in,u,op)) {
992 return 1;
993 } else {
994 return 0;
995 }
996 }
997 }
998 int Asc_UnitSetRealAtomValue(CONST struct Instance *i,
999 char *vstr, char *ustr, unsigned depth)
1000 {
1001 double dval = 0;
1002 char *ends = SNULL;
1003
1004 /* check instance validity */
1005 if (!i || (!(InstanceKind(i)==REAL_INST)
1006 && !(InstanceKind(i)==REAL_ATOM_INST)
1007 && !(InstanceKind(i)==REAL_CONSTANT_INST)
1008 )) {
1009 return 4;
1010 }
1011 /* get number from vstr */
1012 if (!vstr) {
1013 return 5;
1014 }
1015 dval = strtod(vstr,&ends);
1016 if (ends==vstr) {
1017 return 5;
1018 }
1019
1020 /* get valid units struct */
1021 if (ustr==NULL || strlen(ustr)==0 || strcmp(ustr,"*")==0) {
1022 SetRealAtomValue((struct Instance *)i,dval,depth);
1023 } else {
1024 dim_type *dimp = NULL;
1025 double sival = (double)0.0;
1026 struct Units *up = (struct Units *)LookupUnits(ustr);
1027
1028 if (up==NULL) {
1029 unsigned long pos;
1030 int ecode;
1031 up = (struct Units *)FindOrDefineUnits(ustr,&pos,&ecode);
1032 if (up==NULL) {
1033 return 1;
1034 }
1035 }
1036 dimp = (dim_type *)UnitsDimensions(up);
1037 assert(dimp!=NULL /* null dims returned by FindOrDefineUnits */);
1038
1039 /* assign dimensionality if wild, or check for dim incompatibility. */
1040 if (IsWild(RealAtomDims(i))) {
1041 SetRealAtomDims((struct Instance *)i,dimp);
1042 } else if ( CmpDimen(dimp,RealAtomDims(i)) ) {
1043 return 2;
1044 }
1045 /* convert to SI, and assign if ok */
1046 if (Unit_UnconvertReal(dval,up,&sival)) {
1047 return 3;
1048 }
1049 SetRealAtomValue((struct Instance *)i,sival,depth);
1050 }
1051 return 0;
1052 }
1053
1054 /* assumes the tcl unitsinterp is set before entry. else does nothing.
1055 */
1056 static
1057 void Unit_GetUserSet(struct DisplayUnit *du)
1058 {
1059 if (!unitsinterp) {
1060 return;
1061 }
1062 if (du->u!=NULL && UnitsDescription(du->u)!=NULL) {
1063 Tcl_AppendElement(unitsinterp,(char *)UnitsDescription(du->u));
1064 }
1065 }
1066
1067 /********************* END INTERNALS ******************************/
1068
1069 int Asc_UnitDestroyDisplayList(ClientData cdata, Tcl_Interp *interp,
1070 int argc, CONST84 char *argv[])
1071 {
1072 UNUSED_PARAMETER(cdata);
1073 (void)interp; /* stop gcc whine about unused parameter */
1074 (void)argv; /* stop gcc whine about unused parameter */
1075
1076 if ( argc != 1 ) {
1077 return TCL_ERROR;
1078 }
1079 destroy_DUList();
1080 return TCL_OK;
1081 }
1082
1083
1084 int Asc_UnitDefaultBaseUnits(ClientData cdata, Tcl_Interp *interp,
1085 int argc, CONST84 char *argv[])
1086 {
1087 static int SIset;
1088 int i;
1089
1090 UNUSED_PARAMETER(cdata);
1091 (void)interp; /* stop gcc whine about unused parameter */
1092 (void)argc; /* stop gcc whine about unused parameter */
1093 (void)argv; /* stop gcc whine about unused parameter */
1094
1095 if (!SIset) {
1096 g_SI_units[D_MASS]=
1097 (struct Units *)LookupUnits(UNIT_BASE_MASS);
1098 g_SI_units[D_QUANTITY]=
1099 (struct Units *)LookupUnits(UNIT_BASE_QUANTITY);
1100 g_SI_units[D_LENGTH]=
1101 (struct Units *)LookupUnits(UNIT_BASE_LENGTH);
1102 g_SI_units[D_TIME]=
1103 (struct Units *)LookupUnits(UNIT_BASE_TIME);
1104 g_SI_units[D_TEMPERATURE]=
1105 (struct Units *)LookupUnits(UNIT_BASE_TEMPERATURE);
1106 g_SI_units[D_CURRENCY]=
1107 (struct Units *)LookupUnits(UNIT_BASE_CURRENCY);
1108 g_SI_units[D_ELECTRIC_CURRENT]=
1109 (struct Units *)LookupUnits(UNIT_BASE_ELECTRIC_CURRENT);
1110 g_SI_units[D_LUMINOUS_INTENSITY]=
1111 (struct Units *)LookupUnits(UNIT_BASE_LUMINOUS_INTENSITY);
1112 g_SI_units[D_PLANE_ANGLE]=
1113 (struct Units *)LookupUnits(UNIT_BASE_PLANE_ANGLE);
1114 g_SI_units[D_SOLID_ANGLE]=
1115 (struct Units *)LookupUnits(UNIT_BASE_SOLID_ANGLE);
1116 SIset = 1;
1117 for (i = 0;i<NUM_DIMENS;i++) {
1118 assert(g_SI_units[i]!=NULL);
1119 }
1120 }
1121 for (i = 0;i<NUM_DIMENS;i++) {
1122 g_base_units[i]=g_SI_units[i];
1123 }
1124 return TCL_OK;
1125 }
1126
1127 int Asc_UnitGetBaseUnits(ClientData cdata, Tcl_Interp *interp,
1128 int argc, CONST84 char *argv[])
1129 {
1130 int i;
1131 check_units_set(cdata, interp, argc, argv);
1132 for (i = 0; i<NUM_DIMENS; i++) {
1133 if (g_base_units[i]!=NULL) {
1134 Tcl_AppendElement(interp,(char *)UnitsDescription(g_base_units[i]));
1135 } else {
1136 Tcl_AppendElement(interp,(char *)"undefined!");
1137 }
1138 }
1139 return TCL_OK;
1140 }
1141
1142 int Asc_UnitDump(ClientData cdata, Tcl_Interp *interp,
1143 int argc, CONST84 char *argv[])
1144 {
1145 int dev,status = TCL_OK, tmpi;
1146 FILE * fp;
1147
1148 UNUSED_PARAMETER(cdata);
1149
1150 if (( argc < 2 ) || ( argc > 3 )) {
1151 FPRINTF(stderr,"call is: u_dump <device #> \n");
1152 Tcl_SetResult(interp, "u_dump <arg> expects 0,1,2 for #.", TCL_STATIC);
1153 return TCL_ERROR;
1154 }
1155
1156 tmpi = 3;
1157 status = Tcl_GetInt(interp,argv[1],&tmpi);
1158 if (tmpi<0 || tmpi >2) {
1159 status = TCL_ERROR;
1160 }
1161 if (status!=TCL_OK) {
1162 FPRINTF(stderr,"u_dump: first arg is 0,1, or 2\n");
1163 Tcl_ResetResult(interp);
1164 Tcl_SetResult(interp, "u_dump: invalid output dev #", TCL_STATIC);
1165 return status;
1166 } else {
1167 dev = tmpi;
1168 }
1169
1170 switch (dev) {
1171 case 0: fp = stdout;
1172 break;
1173 case 1: fp = stderr;
1174 break;
1175 case 2: fp = NULL;
1176 break;
1177 default : /* should never be here */
1178 FPRINTF(stderr,"u_dump called with strange i/o option!!\n");
1179 return TCL_ERROR;
1180 }
1181
1182 if (fp==NULL) {
1183 char a[1024];
1184 register unsigned long c;
1185 struct Units *p;
1186 for(c = 0;c<UNITS_HASH_SIZE;c++) {
1187 for(p = g_units_hash_table[c];p!=NULL;p = p->next) {
1188 if ( argc == 3 ) {
1189 sprintf(a,"%20s %20.15g ",
1190 SCP(UnitsDescription(p)),
1191 UnitsConvFactor(p));
1192 } else {
1193 /* pretty was asked not asked for */
1194 char *ussi;
1195 char *dimstr;
1196 ussi = UnitsStringSI(p);
1197 dimstr = WriteDimensionString(UnitsDimensions(p));
1198 sprintf(a,"%p %s %.16g %s %s",
1199 (void *)UnitsDimensions(p),
1200 SCP(UnitsDescription(p)),
1201 UnitsConvFactor(p),
1202 UnitsStringSI(p),
1203 (dimstr==NULL)?"":dimstr);
1204 if (dimstr != NULL) {
1205 ascfree(dimstr);
1206 }
1207 ascfree(ussi);
1208 }
1209
1210 Tcl_AppendElement(interp,a);
1211 }
1212 }
1213 } else {
1214 DumpUnits(fp);
1215 }
1216 return TCL_OK;
1217 }
1218
1219 int Asc_DimenDump(ClientData cdata, Tcl_Interp *interp,
1220 int argc, CONST84 char *argv[])
1221 {
1222 int dev,status = TCL_OK, tmpi;
1223 FILE * fp;
1224
1225 UNUSED_PARAMETER(cdata);
1226
1227 if ( argc != 2 ) {
1228 FPRINTF(stderr,"call is: u_dims <device #> \n");
1229 Tcl_SetResult(interp, "u_dims <arg> expects 0,1,2 for #.", TCL_STATIC);
1230 return TCL_ERROR;
1231 }
1232
1233 tmpi = 3;
1234 status = Tcl_GetInt(interp,argv[1],&tmpi);
1235 if (tmpi<0 || tmpi >2) {
1236 status = TCL_ERROR;
1237 }
1238 if (status!=TCL_OK) {
1239 FPRINTF(stderr,"u_dims: first arg is 0,1, or 2\n");
1240 Tcl_ResetResult(interp);
1241 Tcl_SetResult(interp, "u_dims: invalid output dev #", TCL_STATIC);
1242 return status;
1243 } else {
1244 dev = tmpi;
1245 }
1246
1247 switch (dev) {
1248 case 0: fp = stdout;
1249 break;
1250 case 1: fp = stderr;
1251 break;
1252 case 2: fp = NULL;
1253 break;
1254 default : /* should never be here */
1255 FPRINTF(stderr,"u_dims called with strange i/o option!!\n");
1256 return TCL_ERROR;
1257 }
1258
1259 if (!fp) {
1260 char a[1024];
1261 register unsigned long c,len = gl_length(g_dimen_list);
1262 dim_type *d;
1263 for(c = 1;c<=len;c++) {
1264 d = (dim_type *)gl_fetch(g_dimen_list,c);
1265 if (IsWild(d)) {
1266 sprintf(a,"wild");
1267 } else {
1268 sprintf(a,"%s","\0");
1269 }
1270 if (CmpDimen(d,Dimensionless())!=0) {
1271 Asc_BrowWriteDimensions(a,d);
1272 }
1273 Tcl_AppendResult(interp," {",a,"}",SNULL);
1274 }
1275
1276 } else {
1277 DumpDimens(fp);
1278 }
1279 return TCL_OK;
1280 }
1281
1282 int Asc_DimenRelCheck(ClientData cdata, Tcl_Interp *interp,
1283 int argc, CONST84 char *argv[]) {
1284 int status,tmpi;
1285
1286 UNUSED_PARAMETER(cdata);
1287
1288 if ( argc != 2 ) {
1289 FPRINTF(stderr,"call is: u_dim_setverify <0,1>\n");
1290 Tcl_SetResult(interp, "u_dim_setverify expects a number 0 or 1.",
1291 TCL_STATIC);
1292 return TCL_ERROR;
1293 }
1294 tmpi = 2;
1295 status = Tcl_GetInt(interp,argv[1],&tmpi);
1296 if (tmpi<0 || tmpi>1) {
1297 status = TCL_ERROR;
1298 }
1299 if (status!=TCL_OK) {
1300 FPRINTF(stderr,"u_dim_setverify: value must be 0 or 1");
1301 Tcl_ResetResult(interp);
1302 Tcl_SetResult(interp, "u_dim_setverify: invalid boolean given.",
1303 TCL_STATIC);
1304 return status;
1305 }
1306 g_check_dimensions_noisy = tmpi;
1307 return TCL_OK;
1308 }
1309 int Asc_UnitBaseDimToNum(ClientData cdata, Tcl_Interp *interp,
1310 int argc, CONST84 char *argv[])
1311 {
1312 char tmps[4];
1313 char *c;
1314 int i;
1315
1316 UNUSED_PARAMETER(cdata);
1317
1318 if ( argc != 2 ) {
1319 FPRINTF(stderr,"call is: u_dim2num <M,T,L,C,Q,TMP,P,S,E,LUM> \n");
1320 Tcl_SetResult(interp, "u_dim2num expects 1 argument", TCL_STATIC);
1321 return TCL_ERROR;
1322 }
1323 c = QUIET(argv[1]);
1324 for( i = 0; i < NUM_DIMENS && strcmp(c,DimName(i)); i++ );
1325 if( i == NUM_DIMENS ) {
1326 Tcl_SetResult(interp, "u_dim2num called with unknown base dimension.",
1327 TCL_STATIC);
1328 return TCL_ERROR;
1329 } else {
1330 sprintf(tmps,"%d",i);
1331 }
1332 Tcl_AppendResult(interp,tmps,SNULL);
1333 return TCL_OK;
1334 }
1335
1336 int Asc_UnitNumToBaseDim(ClientData cdata, Tcl_Interp *interp,
1337 int argc, CONST84 char *argv[])
1338 {
1339 int status = TCL_OK, tmpi;
1340
1341 UNUSED_PARAMETER(cdata);
1342
1343 if ( argc != 2 ) {
1344 FPRINTF(stderr,"call is: u_num2dim <num> \n");
1345 Tcl_SetResult(interp, "u_num2dim <arg>", TCL_STATIC);
1346 return TCL_ERROR;
1347 }
1348 tmpi = 100;
1349 status = Tcl_GetInt(interp,argv[1],&tmpi);
1350 if (tmpi<0 || tmpi>=NUM_DIMENS) {
1351 status = TCL_ERROR;
1352 }
1353 if (status!=TCL_OK) {
1354 FPRINTF(stderr,"u_num2dim: arg is in range 0 - %d\n",(NUM_DIMENS-1));
1355 Tcl_ResetResult(interp);
1356 Tcl_SetResult(interp, "u_num2dim: invalid dim #", TCL_STATIC);
1357 return status;
1358 }
1359 Tcl_AppendResult(interp,DimName(tmpi),SNULL);
1360 return TCL_OK;
1361 }
1362
1363 int Asc_UnitMatchBaseDim(ClientData cdata, Tcl_Interp *interp,
1364 int argc, CONST84 char *argv[])
1365 {
1366 int status = TCL_OK;
1367 int tmpi;
1368
1369 if ( argc != 2 ) {
1370 FPRINTF(stderr,"call is: u_num2dim <num> \n");
1371 Tcl_SetResult(interp, "u_num2dim <arg>", TCL_STATIC);
1372 return TCL_ERROR;
1373 }
1374 tmpi = 100;
1375 status = Tcl_GetInt(interp,argv[1],&tmpi);
1376 if (tmpi<0 || tmpi>=NUM_DIMENS) {
1377 status = TCL_ERROR;
1378 }
1379 if (status!=TCL_OK) {
1380 FPRINTF(stderr,"u_frombasedim: arg is in range 0 - %d\n",
1381 (NUM_DIMENS-1));
1382 Tcl_ResetResult(interp);
1383 Tcl_SetResult(interp, "u_frombasedim: invalid dim #", TCL_STATIC);
1384 return status;
1385 }
1386 status = Asc_UnitNumToBaseDim(cdata,interp,argc,argv);
1387 if (status ==TCL_OK) {
1388 dim_type dim;
1389 struct gl_list_t *ulist = gl_create(50L);
1390 register unsigned long c;
1391 struct Units *p;
1392
1393 ClearDimensions(&dim);
1394 ParseDim(&dim,Tcl_GetStringResult(interp));
1395 Tcl_ResetResult(interp);
1396 for(c = 0;c<UNITS_HASH_SIZE;c++) {
1397 for(p = g_units_hash_table[c];p!=NULL;p = p->next) {
1398 if (CmpDimen(&dim,UnitsDimensions(p))==0) {
1399 gl_insert_sorted(ulist,(VOIDPTR)p,(CmpFunc)Unit_CmpConv);
1400 }
1401 }
1402 }
1403 for(c = 1;c<=gl_length(ulist);c++) {
1404 Tcl_AppendElement(interp,
1405 (char *)UnitsDescription((struct Units *)gl_fetch(ulist,c)));
1406 }
1407 gl_destroy(ulist);
1408 } else {
1409 Tcl_AppendResult(interp," called from u_frombasedim",SNULL);
1410 }
1411 return status;
1412 }
1413
1414 int Asc_UnitMatchAtomDim(ClientData cdata, Tcl_Interp *interp,
1415 int argc, CONST84 char *argv[])
1416 {
1417 struct TypeDescription *desc;
1418
1419 UNUSED_PARAMETER(cdata);
1420
1421 if ( argc != 2 ) {
1422 FPRINTF(stderr,"call is: u_fromatomdim <atom_typename> \n");
1423 Tcl_SetResult(interp, "u_fromatomdim: expects atom type.", TCL_STATIC);
1424 return TCL_ERROR;
1425 }
1426 desc = UnitsFindType(argv[1]);
1427 if (desc!=NULL && GetBaseType(desc)==real_type) {
1428 dim_type *dim = (dim_type *)GetRealDimens(desc);
1429 struct gl_list_t *ulist = gl_create(50L);
1430 register unsigned long c;
1431 struct Units *p;
1432
1433 for(c = 0;c<UNITS_HASH_SIZE;c++) {
1434 for(p = g_units_hash_table[c];p!=NULL;p = p->next) {
1435 if (CmpDimen(dim,UnitsDimensions(p))==0) {
1436 gl_insert_sorted(ulist,(VOIDPTR)p,(CmpFunc)Unit_CmpConv);
1437 }
1438 }
1439 }
1440 for(c = 1;c<=gl_length(ulist);c++) {
1441 Tcl_AppendElement(interp,
1442 (char *)UnitsDescription((struct Units *)gl_fetch(ulist,c)));
1443 }
1444 gl_destroy(ulist);
1445 } else {
1446 Tcl_SetResult(interp, "u_fromatomdim called with bad real atom name",
1447 TCL_STATIC);
1448 return TCL_ERROR;
1449 }
1450 return TCL_OK;
1451 }
1452
1453 int Asc_UnitGetAtomList(ClientData cdata, Tcl_Interp *interp,
1454 int argc, CONST84 char *argv[])
1455 {
1456 struct gl_list_t *alist = gl_create(200L);
1457 struct gl_list_t *dlist = NULL;
1458 register struct TypeDescription *desc, *rtdesc;
1459 register dim_type *dim;
1460 register unsigned long c,len;
1461 char a[1024];
1462
1463 UNUSED_PARAMETER(cdata);
1464 (void)argv; /* stop gcc whine about unused parameter */
1465
1466 if ( argc != 1 ) {
1467 FPRINTF(stderr,"call is: u_getdimatoms <no args> \n");
1468 Tcl_SetResult(interp, "u_getdimatoms: unexpected arg found.", TCL_STATIC);
1469 return TCL_ERROR;
1470 }
1471 rtdesc = UnitsFindType("real");
1472 assert(rtdesc);
1473 dlist = DefinitionList();
1474 if (!dlist) {
1475 Tcl_SetResult(interp, "u_getdimatoms found no type definitions.",
1476 TCL_STATIC);
1477 return TCL_ERROR;
1478 }
1479 len = gl_length(dlist);
1480 for(c = 1;c<=len;c++) {
1481 desc = (struct TypeDescription *)gl_fetch(dlist,c);
1482 if (desc) {/* MoreRefined doesn't take kindly to null */
1483 if (MoreRefined(desc,rtdesc)) {
1484 dim = (dim_type *)GetRealDimens(desc);
1485 if (CmpDimen(dim,Dimensionless())!=0 && !IsWild(dim)) {
1486 gl_insert_sorted(alist,(VOIDPTR)desc,(CmpFunc)Unit_CmpAtomName);
1487 }
1488 }
1489 }
1490 }
1491 gl_destroy(dlist);
1492 len = gl_length(alist);
1493 for(c = 1;c<=len;c++) {
1494 desc = (struct TypeDescription *)gl_fetch(alist,c);
1495 sprintf(a,"%s ",(char *)SCP(GetName(desc)));
1496 Asc_BrowWriteDimensions(a,GetRealDimens(desc));
1497 Tcl_AppendElement(interp,a);
1498 }
1499 gl_destroy(alist);
1500 return TCL_OK;
1501 }
1502
1503 int Asc_UnitChangeBaseUnit(ClientData cdata, Tcl_Interp *interp,
1504 int argc, CONST84 char *argv[])
1505 {
1506 struct Units *up = NULL;
1507 if ( argc != 2 ) {
1508 FPRINTF(stderr,"call is: u_change_baseunit <unit>\n");
1509 Tcl_SetResult(interp, "u_change_baseunit wants a simple unit arg",
1510 TCL_STATIC);
1511 return TCL_ERROR;
1512 }
1513 check_units_set(cdata,interp,argc,argv);
1514 check_DU_set();
1515 up = (struct Units *)LookupUnits(argv[1]);
1516 if (up != NULL) {
1517 int c;
1518 for(c = 0;
1519 ((c < (NUM_DIMENS))
1520 && CmpDimen(UnitsDimensions(up),UnitsDimensions(g_base_units[c]))!=0);
1521 c++);
1522 if (c==(NUM_DIMENS)) {
1523 Tcl_SetResult(interp,
1524 "u_change_baseunit called with non-base dimensioned unit",
1525 TCL_STATIC);
1526 return TCL_ERROR;
1527 }
1528 g_base_units[c]=up;
1529 updatefundunitdim = -1;
1530 for (c = 0;updatefundunitdim<0 && c<NUM_DIMENS;c++) {
1531 if (Numerator(GetDimFraction(*(UnitsDimensions(up)),c)) != 0 ) {
1532 updatefundunitdim = c;
1533 }
1534 }
1535 gl_iterate( DUList, (void (*)(VOIDPTR))Unit_UpdateFundUnits );
1536 return TCL_OK;
1537 } else {
1538 Tcl_SetResult(interp, "u_change_baseunit called with unknown unit.",
1539 TCL_STATIC);
1540 return TCL_ERROR;
1541 }
1542 }
1543
1544 int Asc_UnitSetUser(ClientData cdata, Tcl_Interp *interp,
1545 int argc, CONST84 char *argv[])
1546 {
1547 struct Units *up = NULL;
1548 struct DisplayUnit *du;
1549 if ( argc != 2 ) {
1550 FPRINTF(stderr,"call is: u_set_user <unit>\n");
1551 Tcl_SetResult(interp, "u_set_user wants a units string arg", TCL_STATIC);
1552 return TCL_ERROR;
1553 }
1554 check_units_set(cdata,interp,argc,argv);
1555 check_DU_set();
1556 up = (struct Units *)LookupUnits(argv[1]);
1557 if (up ==NULL) {
1558 unsigned long pos;
1559 int ecode;
1560 up = (struct Units *)FindOrDefineUnits(argv[1],&pos,&ecode);
1561 }
1562 if (up!=NULL) {
1563 du = Unit_FindOrAddDU((dim_type *)UnitsDimensions(up));
1564 du->u = up;
1565 return TCL_OK;
1566 }
1567 Tcl_SetResult(interp, "u_set_user unable to parse the units given.",
1568 TCL_STATIC);
1569 return TCL_ERROR;
1570 }
1571
1572 /*
1573 * return all real atoms and real constants which have the units
1574 * given.
1575 */
1576 int Asc_UnitGetAtomsForUnit(ClientData cdata, Tcl_Interp *interp,
1577 int argc, CONST84 char *argv[])
1578 {
1579 struct TypeDescription *desc, *rtdesc, *rcdesc;
1580 struct Units *up = NULL;
1581 struct DisplayUnit *du;
1582 unsigned long c,len;
1583 struct gl_list_t *dlist, *alist, *blist;
1584 dim_type *dim;
1585 unsigned long pos;
1586 int ecode;
1587
1588 if ( argc != 2 ) {
1589 FPRINTF(stderr,"call is: u_get_atoms <unit>\n");
1590 Tcl_SetResult(interp, "u_get_atoms wants a units string arg", TCL_STATIC);
1591 return TCL_ERROR;
1592 }
1593 check_units_set(cdata,interp,argc,argv);
1594 check_DU_set();
1595 up = (struct Units *)LookupUnits(argv[1]);
1596 if (up == NULL) {
1597 up = (struct Units *)FindOrDefineUnits(argv[1],&pos,&ecode);
1598 }
1599 if (up != NULL) {
1600 du = Unit_FindOrAddDU((dim_type *)UnitsDimensions(up));
1601 du->u = up;
1602 } else {
1603 Tcl_SetResult(interp, "u_get_atoms unable to parse the units given.",
1604 TCL_STATIC);
1605 return TCL_ERROR;
1606 }
1607 rtdesc = UnitsFindType("real");
1608 rcdesc = UnitsFindType("real_constant");
1609 assert(rtdesc);
1610 assert(rcdesc);
1611 dlist = DefinitionList();
1612 if (!dlist) {
1613 Tcl_SetResult(interp, "u_get_atoms found no type definitions.",
1614 TCL_STATIC);
1615 return TCL_ERROR;
1616 }
1617 len = gl_length(dlist);
1618 alist = gl_create(len);
1619 blist = gl_create(len);
1620 for(c = 1;c<=len;c++) {
1621 desc = (struct TypeDescription *)gl_fetch(dlist,c);
1622 if (desc != NULL) {/* MoreRefined doesn't take kindly to null */
1623 if (MoreRefined(desc,rtdesc)!= NULL) {
1624 dim = (dim_type *)GetRealDimens(desc);
1625 if (CmpDimen(dim,du->d) == 0 && !IsWild(dim)) {
1626 gl_insert_sorted(alist,(VOIDPTR)desc,(CmpFunc)Unit_CmpAtomName);
1627 }
1628 } else {
1629 if (MoreRefined(desc,rcdesc) != NULL) {
1630 dim = (dim_type *)GetConstantDimens(desc);
1631 if (dim != NULL && CmpDimen(dim,du->d) == 0 && !IsWild(dim)) {
1632 gl_insert_sorted(blist,(VOIDPTR)desc,(CmpFunc)Unit_CmpAtomName);
1633 }
1634 }
1635 }
1636 }
1637 }
1638 gl_destroy(dlist);
1639
1640 len = gl_length(alist);
1641 for(c = 1;c<=len;c++) {
1642 desc = (struct TypeDescription *)gl_fetch(alist,c);
1643 Tcl_AppendElement(interp,(char *)SCP(GetName(desc)));
1644 }
1645 gl_destroy(alist);
1646
1647 len = gl_length(blist);
1648 for(c = 1;c<=len;c++) {
1649 desc = (struct TypeDescription *)gl_fetch(blist,c);
1650 Tcl_AppendElement(interp,(char *)SCP(GetName(desc)));
1651 }
1652 gl_destroy(blist);
1653 return TCL_OK;
1654 }
1655
1656
1657 int Asc_UnitGetPrec(ClientData cdata, Tcl_Interp *interp,
1658 int argc, CONST84 char *argv[])
1659 {
1660 char buf[MAXIMUM_NUMERIC_LENGTH]; /* string to hold integer */
1661 UNUSED_PARAMETER(cdata);
1662 (void)argv; /* stop gcc whine about unused parameter */
1663
1664 if ( argc != 1 ) {
1665 FPRINTF(stderr,"call is: u_getprec <no args>\n");
1666 Tcl_SetResult(interp, "u_getprec expects no arguments.", TCL_STATIC);
1667 return TCL_ERROR;
1668 }
1669 sprintf(buf,"%d",UPREC);
1670 Tcl_SetResult(interp, buf, TCL_VOLATILE);
1671 return TCL_OK;
1672 }
1673
1674 int Asc_UnitGetCPrec()
1675 {
1676 return UPREC;
1677 }
1678
1679 int Asc_UnitSetPrec(ClientData cdata, Tcl_Interp *interp,
1680 int argc, CONST84 char *argv[])
1681 {
1682 int status,tmpi;
1683
1684 UNUSED_PARAMETER(cdata);
1685
1686 if ( argc != 2 ) {
1687 FPRINTF(stderr,"call is: u_setprec <number>\n");
1688 Tcl_SetResult(interp, "u_setprec expects a number 4 to 16.", TCL_STATIC);
1689 return TCL_ERROR;
1690 }
1691 tmpi = 100;
1692 status = Tcl_GetInt(interp,argv[1],&tmpi);
1693 if (tmpi<4 || tmpi>16) {
1694 status = TCL_ERROR;
1695 }
1696 if (status!=TCL_OK) {
1697 FPRINTF(stderr,"u_setprec: Precision must be in range 4 - 16");
1698 Tcl_ResetResult(interp);
1699 Tcl_SetResult(interp, "u_setprec: invalid precision specified.",
1700 TCL_STATIC);
1701 return status;
1702 }
1703 UPREC = tmpi;
1704 return TCL_OK;
1705 }
1706
1707 int Asc_UnitGetUnits(ClientData cdata, Tcl_Interp *interp,
1708 int argc, CONST84 char *argv[])
1709 {
1710 struct TypeDescription *desc;
1711
1712 UNUSED_PARAMETER(cdata);
1713
1714 if ( argc != 2 ) {
1715 FPRINTF(stderr,"call is: u_get_units <atom_typename> \n");
1716 Tcl_SetResult(interp, "u_get_units: expects atom type.", TCL_STATIC);
1717 return TCL_ERROR;
1718 }
1719 desc = UnitsFindType(argv[1]);
1720 if (desc!=NULL && GetBaseType(desc)==real_type) {
1721 dim_type *dim = (dim_type *)GetRealDimens(desc);
1722 struct DisplayUnit *du;
1723 assert(dim!=NULL);
1724 if (IsWild(dim) || CmpDimen(dim,Dimensionless())==0 ) {
1725 return TCL_OK;
1726 }
1727 du = Unit_FindOrAddDU(dim);
1728 if (du->u!=NULL) {
1729 Tcl_AppendResult(interp,UnitsDescription(du->u),SNULL);
1730 return TCL_OK;
1731 }
1732 if (du->fu!=NULL) {
1733 Tcl_AppendResult(interp,UnitsDescription(du->fu),SNULL);
1734 return TCL_OK;
1735 } else {
1736 struct Units *u = Unit_DisplayFund(dim);
1737 if (!u) {
1738 Tcl_SetResult(interp,
1739 "u_get_units: unable to define fundamental units!",
1740 TCL_STATIC);
1741 return TCL_ERROR;
1742 } else {
1743 Tcl_AppendResult(interp,UnitsDescription(u),SNULL);
1744 return TCL_OK;
1745 }
1746 }
1747 } else {
1748 Tcl_SetResult(interp, "u_get_units called with bad real atom name",
1749 TCL_STATIC);
1750 return TCL_ERROR;
1751 }
1752 }
1753
1754 int Asc_UnitGetUser(ClientData cdata, Tcl_Interp *interp,
1755 int argc, CONST84 char *argv[])
1756 {
1757 struct TypeDescription *desc;
1758
1759 UNUSED_PARAMETER(cdata);
1760
1761 if ( argc != 2 ) {
1762 FPRINTF(stderr,"call is: u_get_user <atom_typename> \n");
1763 Tcl_SetResult(interp, "u_get_user: expects atom type.", TCL_STATIC);
1764 return TCL_ERROR;
1765 }
1766 desc = UnitsFindType(argv[1]);
1767 if (desc!=NULL && GetBaseType(desc)==real_type) {
1768 dim_type *dim = (dim_type *)GetRealDimens(desc);
1769 struct Units *u;
1770 assert(dim!=NULL);
1771 if (IsWild(dim) || CmpDimen(dim,Dimensionless())==0 ) {
1772 return TCL_OK;
1773 }
1774 u = Unit_DisplayUnits(dim);
1775 if (u!=NULL) {
1776 Tcl_AppendResult(interp,UnitsDescription(u),SNULL);
1777 } else {
1778 Tcl_SetResult(interp, "default", TCL_STATIC);
1779 }
1780 return TCL_OK;
1781 } else {
1782 Tcl_SetResult(interp, "u_get_user called with bad real atom name",
1783 TCL_STATIC);
1784 return TCL_ERROR;
1785 }
1786 }
1787
1788 int Asc_UnitGetList(ClientData cdata, Tcl_Interp *interp,
1789 int argc, CONST84 char *argv[])
1790 {
1791 UNUSED_PARAMETER(cdata);
1792 (void)argv; /* stop gcc whine about unused parameter */
1793
1794 if ( argc != 1 ) {
1795 FPRINTF(stderr,"call is: u_get_list <no args> \n");
1796 Tcl_SetResult(interp, "u_get_list: expects no arguments.", TCL_STATIC);
1797 return TCL_ERROR;
1798 }
1799 check_DU_set();
1800 unitsinterp = interp;
1801 gl_iterate(DUList,(void (*)(VOIDPTR))Unit_GetUserSet);
1802 return TCL_OK;
1803 }
1804 int Asc_UnitClearUser(ClientData cdata, Tcl_Interp *interp,
1805 int argc, CONST84 char *argv[])
1806 {
1807 struct TypeDescription *desc;
1808
1809 UNUSED_PARAMETER(cdata);
1810
1811 if ( argc != 2 ) {
1812 FPRINTF(stderr,"call is: u_clear_user <atom_typename> \n");
1813 Tcl_SetResult(interp, "u_clear_user: expects atom type.", TCL_STATIC);
1814 return TCL_ERROR;
1815 }
1816 desc = UnitsFindType(argv[1]);
1817 if (desc!=NULL && GetBaseType(desc)==real_type) {
1818 dim_type *dim = (dim_type *)GetRealDimens(desc);
1819 struct DisplayUnit *du;
1820 assert(dim!=NULL);
1821 if (IsWild(dim) || CmpDimen(dim,Dimensionless())==0 ) {
1822 return TCL_OK;
1823 }
1824 du = Unit_FindOrAddDU(dim);
1825 du->u = (struct Units *)NULL;
1826 return TCL_OK;
1827 } else {
1828 Tcl_SetResult(interp, "u_clear_user called with bad real atom name",
1829 TCL_STATIC);
1830 return TCL_ERROR;
1831 }
1832 }
1833
1834 int Asc_UnitGetVal(ClientData cdata, Tcl_Interp *interp,
1835 int argc, CONST84 char *argv[])
1836 {
1837 struct Instance *i;
1838 int status;
1839
1840 UNUSED_PARAMETER(cdata);
1841
1842 if ( argc != 2 ) {
1843 Tcl_SetResult(interp, "u_getval expected <qlfdid>", TCL_STATIC);
1844 return TCL_ERROR;
1845 }
1846 status = Asc_QlfdidSearch3(argv[1],0);
1847 if (status ==0) {
1848 i = g_search_inst;
1849 } else {
1850 Tcl_AppendResult(interp,"u_getval: QlfdidSearchCmd error",
1851 argv[1], " not found.",SNULL);
1852 return TCL_ERROR;
1853 }
1854 if (IsDimInstance(i)) {
1855 Tcl_AppendElement(interp,Asc_UnitValue(i));
1856 } else {
1857 Tcl_SetResult(interp, "u_getval called on undimensioned object.",
1858 TCL_STATIC);
1859 return TCL_ERROR;
1860 }
1861 return TCL_OK;
1862 }
1863
1864 int Asc_UnitBrowGetVal(ClientData cdata, Tcl_Interp *interp,
1865 int argc, CONST84 char *argv[])
1866 {
1867 struct Instance *i;
1868 UNUSED_PARAMETER(cdata);
1869 (void)argv; /* stop gcc whine about unused parameter */
1870
1871 ASCUSE;
1872
1873 if ( argc > 2 ) {
1874 Tcl_SetResult(interp, "u_browgetval [search]", TCL_STATIC);
1875 return TCL_ERROR;
1876 }
1877 if (argc==2) {
1878 if (strncmp(argv[1],"search",3)!=0) {
1879 Tcl_AppendResult(interp, "Error: ",argv[0]," incorrect argument",
1880 argv[1],(char *) NULL);
1881 return TCL_ERROR;
1882 }
1883 i = g_search_inst;
1884 } else {
1885 i = g_curinst;
1886 }
1887 if (IsDimInstance(i)) {
1888 Tcl_AppendElement(interp,Asc_UnitValue(i));
1889 } else {
1890 Tcl_SetResult(interp, "u_browgetval called on undimensioned object.",
1891 TCL_STATIC);
1892 return TCL_ERROR;
1893 }
1894 return TCL_OK;
1895 }
1896
1897 int Asc_UnitSlvGetRelVal(ClientData cdata, Tcl_Interp *interp,
1898 int argc, CONST84 char *argv[])
1899 {
1900 struct rel_relation **rp;
1901 int32 maxrel,relnum;
1902 int status = TCL_OK;
1903
1904 UNUSED_PARAMETER(cdata);
1905
1906 if ( argc != 2 ) {
1907 Tcl_AppendElement(interp,"u_slvgetrelval expects solver relation index.");
1908 return TCL_ERROR;
1909 }
1910 if (g_solvsys_cur==NULL) {
1911 FPRINTF(stderr,"u_slvgetrelval called with NULL pointer\n");
1912 Tcl_AppendElement(interp,"u_slvgetrelval called without slv_system");
1913 return TCL_ERROR;
1914 }
1915 rp = slv_get_solvers_rel_list(g_solvsys_cur);
1916 if (!rp) {
1917 FPRINTF(stderr, "NULL relation list found in u_slvgetrelval\n");
1918 Tcl_AppendElement(interp,"u_slvgetrelval called with null rellist");
1919 return TCL_ERROR;
1920 }
1921 maxrel = (int32)slv_get_num_solvers_rels(g_solvsys_cur);
1922 status = Tcl_GetInt(interp,argv[1],&relnum);
1923 if (relnum>=maxrel||status==TCL_ERROR) {
1924 Tcl_ResetResult(interp);
1925 Tcl_SetResult(interp, "u_slvgetrelval: equation requested does not exist",
1926 TCL_STATIC);
1927 FPRINTF(stderr,"u_slvgetrelval: relation index invalid.\n");
1928 return TCL_ERROR;
1929 }
1930 if ( IsDimInstance( rel_instance(rp[relnum]) ) ) {
1931 Tcl_AppendResult(interp,Asc_UnitValue(rel_instance(rp[relnum])),SNULL);
1932 } else {
1933 Tcl_SetResult(interp, "u_slvgetrelval called on wierd object.",TCL_STATIC);
1934 return TCL_ERROR;
1935 }
1936 return TCL_OK;
1937 }
1938
1939 int Asc_UnitSlvGetVarVal(ClientData cdata, Tcl_Interp *interp,
1940 int argc, CONST84 char *argv[])
1941 {
1942 struct var_variable **vp;
1943 int32 maxvar,varnum;
1944 int status = TCL_OK;
1945
1946 UNUSED_PARAMETER(cdata);
1947
1948 if ( argc != 2 ) {
1949 Tcl_AppendElement(interp,"u_slvgetvarval expects solver variable index.");
1950 return TCL_ERROR;
1951 }
1952 if (g_solvsys_cur==NULL) {
1953 FPRINTF(stderr,"u_slvgetvarval called with NULL pointer\n");
1954 Tcl_AppendElement(interp,"u_slvgetvarval called without slv_system");
1955 return TCL_ERROR;
1956 }
1957 vp = slv_get_solvers_var_list(g_solvsys_cur);
1958 if (!vp) {
1959 FPRINTF(stderr, "NULL variable list found in u_slvgetvarval\n");
1960 Tcl_AppendElement(interp,"u_slvgetvarval called with null varlist");
1961 return TCL_ERROR;
1962 }
1963 maxvar = (int32)slv_get_num_solvers_vars(g_solvsys_cur);
1964 status = Tcl_GetInt(interp,argv[1],&varnum);
1965 if (varnum>=maxvar||status ==TCL_ERROR) {
1966 Tcl_ResetResult(interp);
1967 Tcl_SetResult(interp, "u_slvgetvarval: variable requested does not exist",
1968 TCL_STATIC);
1969 FPRINTF(stderr,"u_slvgetvarval: variable index invalid.\n");
1970 return TCL_ERROR;
1971 }
1972 if (IsDimInstance(var_instance(vp[varnum]))) {
1973 Tcl_AppendResult(interp,Asc_UnitValue(var_instance(vp[varnum])),SNULL);
1974 } else {
1975 Tcl_SetResult(interp, "u_slvgetrelval called on wierd object.",TCL_STATIC);
1976 return TCL_ERROR;
1977 }
1978 return TCL_OK;
1979 }
1980
1981 int Asc_UnitSlvGetObjVal(ClientData cdata, Tcl_Interp *interp,
1982 int argc, CONST84 char *argv[])
1983 {
1984 struct rel_relation **rp;
1985 int32 maxobj,objnum;
1986 int status = TCL_OK;
1987
1988 UNUSED_PARAMETER(cdata);
1989
1990 if ( argc != 2 ) {
1991 Tcl_AppendElement(interp,"u_slvgetobjval expects solver objective index.");
1992 return TCL_ERROR;
1993 }
1994 if (g_solvsys_cur==NULL) {
1995 FPRINTF(stderr,"u_slvgetobjval called with NULL pointer\n");
1996 Tcl_AppendElement(interp,"u_slvgetobjval called without slv_system");
1997 return TCL_ERROR;
1998 }
1999 rp = slv_get_solvers_obj_list(g_solvsys_cur);
2000 if (!rp) {
2001 FPRINTF(stderr, "NULL objective list found in u_slvgetobjval\n");
2002 Tcl_AppendElement(interp,"u_slvgetobjval called with null objlist");
2003 return TCL_ERROR;
2004 }
2005 maxobj = (int32)slv_get_num_solvers_objs(g_solvsys_cur);
2006 status = Tcl_GetInt(interp,argv[1],&objnum);
2007 if (objnum>=maxobj||status==TCL_ERROR) {
2008 Tcl_ResetResult(interp);
2009 Tcl_SetResult(interp, "u_slvgetobjval: objective requested does not exist",
2010 TCL_STATIC);
2011 FPRINTF(stderr,"u_slvgetobjval: objective index invalid.\n");
2012 return TCL_ERROR;
2013 }
2014 if ( IsDimInstance( rel_instance(rp[objnum]) ) ) {
2015 Tcl_AppendResult(interp,Asc_UnitValue(rel_instance(rp[objnum])),SNULL);
2016 } else {
2017 Tcl_SetResult(interp, "u_slvgetobjval called on wierd object.",TCL_STATIC);
2018 return TCL_ERROR;
2019 }
2020 return TCL_OK;
2021
2022
2023
2024 /* OLD CODE HERE TO END
2025 if ( argc != 2 ) {
2026 Tcl_SetResult(interp, "u_slvgetobjval takes no args.", TCL_STATIC);
2027 return TCL_ERROR;
2028 } */
2029 /* write code here when exprdim available */
2030 /* return TCL_OK; */
2031 }
2032
2033
2034 #define LONGHELP(b,ms) ((b)?ms:"")
2035 int Asc_UnitHelpList(ClientData cdata, Tcl_Interp *interp,
2036 int argc, CONST84 char *argv[])
2037 {
2038 boolean detail = 1;
2039
2040 UNUSED_PARAMETER(cdata);
2041
2042 if ( argc > 2 ) {
2043 FPRINTF(stderr,"call is: uhelp [s,l] \n");
2044 Tcl_SetResult(interp, "Too many args to uhelp. Want 0 or 1 args",
2045 TCL_STATIC);
2046 return TCL_ERROR;
2047 }
2048 if ( argc == 2 ) {
2049 if (argv[1][0]=='s') {
2050 detail = 0;
2051 }
2052 if (argv[1][0]=='l') {
2053 detail = 1;
2054 }
2055 PRINTF("%-22s%s\n","u_destroy_list",
2056 LONGHELP(detail,"deallocate display units list"));
2057 PRINTF("%-22s%s\n","u_setSIdef",
2058 LONGHELP(detail,"set SI mks as display base units"));
2059 PRINTF("%-22s%s\n","u_getbasedef",
2060 LONGHELP(detail,"get current display base units list"));
2061 PRINTF("%-22s%s\n","u_dump",
2062 LONGHELP(detail,"dump all global units to out, err or list"));
2063 PRINTF("%-22s%s\n","u_dims",
2064 LONGHELP(detail,"dump all global dims to out, err or list"));
2065 PRINTF("%-22s%s\n","u_dim_setverify",
2066 LONGHELP(detail,"turn relation dim checking noise on or off"));
2067
2068 PRINTF("%-22s%s\n","u_num2dim",
2069 LONGHELP(detail,"return simple dimension corresponding to num"));
2070 PRINTF("%-22s%s\n","u_dim2num",
2071 LONGHELP(detail,"return number of a simple dimension"));
2072 PRINTF("%-22s%s\n","u_frombasedim",
2073 LONGHELP(detail,"return all unit names matching base dimension"));
2074 PRINTF("%-22s%s\n","u_fromatomdim",
2075 LONGHELP(detail,"return unit names matching atom dimension set"));
2076
2077 PRINTF("%-22s%s\n","u_getdimatoms",
2078 LONGHELP(detail,"get list of dimensioned atoms"));
2079 PRINTF("%-22s%s\n","u_get_atoms",
2080 LONGHELP(detail,"get list of atoms matching units given"));
2081 PRINTF("%-22s%s\n","u_change_baseunit",
2082 LONGHELP(detail,"change the display default unit for a dimension"));
2083 PRINTF("%-22s%s\n","u_getprec",
2084 LONGHELP(detail,"get current display value precision"));
2085 PRINTF("%-22s%s\n","u_setprec",
2086 LONGHELP(detail,"set new display value precision"));
2087
2088 PRINTF("%-22s%s\n","u_get_units",
2089 LONGHELP(detail,"get display units of dimensioned atom type"));
2090 PRINTF("%-22s%s\n","u_set_user",
2091 LONGHELP(detail,"set user display units in string given"));
2092 PRINTF("%-22s%s\n","u_get_list",
2093 LONGHELP(detail,"get all user set display units"));
2094 PRINTF("%-22s%s\n","u_get_user",
2095 LONGHELP(detail,"get user set display units of dimensioned atom type"));
2096 PRINTF("%-22s%s\n","u_clear_user",
2097 LONGHELP(detail,"unset user set display units of dimensioned atom"));
2098
2099 PRINTF("%-22s%s\n","u_getval",
2100 LONGHELP(detail,"get value and units of qlfdid"));
2101 PRINTF("%-22s%s\n","u_browgetval",
2102 LONGHELP(detail,"get value and units of g_curinst"));
2103 PRINTF("%-22s%s\n","u_slvgetrelval",
2104 LONGHELP(detail,"get value and units of indexed relation resid"));
2105 PRINTF("%-22s%s\n","u_slvgetvarval",
2106 LONGHELP(detail,"get value and units of indexed variable"));
2107 PRINTF("%-22s%s\n","u_slvgetobjval",
2108 LONGHELP(detail,"get value and units of objective"));
2109
2110 PRINTF("%-22s%s\n","uhelp",
2111 LONGHELP(detail,"uhelp s(=names only) l(=this list)."));
2112
2113 PRINTF("\n");
2114 }
2115 if ( argc == 1 ) {
2116 char * tmps;
2117 tmps = (char *)ascmalloc((MAXIMUM_NUMERIC_LENGTH+1)*sizeof(char));
2118
2119 sprintf(tmps,"u_destroy_list");
2120 Tcl_AppendElement(interp,tmps);
2121 sprintf(tmps,"u_setSIdef");
2122 Tcl_AppendElement(interp,tmps);
2123 sprintf(tmps,"u_getbasedef");
2124 Tcl_AppendElement(interp,tmps);
2125 sprintf(tmps,"u_dump");
2126 Tcl_AppendElement(interp,tmps);
2127 sprintf(tmps,"u_dims");
2128 Tcl_AppendElement(interp,tmps);
2129 sprintf(tmps,"u_dim_setverify");
2130 Tcl_AppendElement(interp,tmps);
2131
2132 sprintf(tmps,"u_num2dim");
2133 Tcl_AppendElement(interp,tmps);
2134 sprintf(tmps,"u_dim2num");
2135 Tcl_AppendElement(interp,tmps);
2136 sprintf(tmps,"u_frombasedim");
2137 Tcl_AppendElement(interp,tmps);
2138 sprintf(tmps,"u_fromatomdim");
2139 Tcl_AppendElement(interp,tmps);
2140
2141 sprintf(tmps,"u_getdimatoms");
2142 Tcl_AppendElement(interp,tmps);
2143 sprintf(tmps,"u_get_atoms");
2144 Tcl_AppendElement(interp,tmps);
2145 sprintf(tmps,"u_change_baseunit");
2146 Tcl_AppendElement(interp,tmps);
2147 sprintf(tmps,"u_getprec");
2148 Tcl_AppendElement(interp,tmps);
2149 sprintf(tmps,"u_setprec");
2150 Tcl_AppendElement(interp,tmps);
2151
2152 sprintf(tmps,"u_get_units");
2153 Tcl_AppendElement(interp,tmps);
2154 sprintf(tmps,"u_set_user");
2155 Tcl_AppendElement(interp,tmps);
2156 sprintf(tmps,"u_get_user");
2157 Tcl_AppendElement(interp,tmps);
2158 sprintf(tmps,"u_get_list");
2159 Tcl_AppendElement(interp,tmps);
2160 sprintf(tmps,"u_clear_user");
2161 Tcl_AppendElement(interp,tmps);
2162
2163 sprintf(tmps,"u_getval");
2164 Tcl_AppendElement(interp,tmps);
2165 sprintf(tmps,"u_browgetval");
2166 Tcl_AppendElement(interp,tmps);
2167
2168 sprintf(tmps,"u_slvgetrelval");
2169 Tcl_AppendElement(interp,tmps);
2170 sprintf(tmps,"u_slvgetvarval");
2171 Tcl_AppendElement(interp,tmps);
2172 sprintf(tmps,"u_slvgetobjval");
2173 Tcl_AppendElement(interp,tmps);
2174
2175 sprintf(tmps,"uhelp");
2176 Tcl_AppendElement(interp,tmps);
2177 ascfree(tmps);
2178 }
2179 return TCL_OK;
2180 }
2181

john.pye@anu.edu.au
ViewVC Help
Powered by ViewVC 1.1.22