Bug Summary

File:capsValue.c
Warning:line 895, column 16
Array access (from variable 'reals') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name capsValue.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=none -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib/llvm-10/lib/clang/10.0.0 -D REVISION=7.6 -I ../include -I /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/ESP/LINUX64/include -I . -I /usr/include/udunits2 -internal-isystem /usr/local/include -internal-isystem /usr/lib/llvm-10/lib/clang/10.0.0/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-dangling-else -Wno-parentheses -Wno-unused-result -Wno-format-truncation -fdebug-compilation-dir /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/CAPS/src -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -vectorize-loops -vectorize-slp -analyzer-output=html -faddrsig -o /home/jenkins/workspace/ESP_Stanalizer/LINUX64/CAPS/scan-build/scanCAPS/2022-02-28-212352-64886-1 -x c capsValue.c
1/*
2 * CAPS: Computational Aircraft Prototype Syntheses
3 *
4 * Value Object Functions
5 *
6 * Copyright 2014-2022, Massachusetts Institute of Technology
7 * Licensed under The GNU Lesser General Public License, version 2.1
8 * See http://www.opensource.org/licenses/lgpl-2.1.php
9 *
10 */
11
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <math.h>
16
17#ifdef WIN32
18#define getcwd _getcwd
19#define PATH_MAX4096 _MAX_PATH
20#define snprintf _snprintf
21#else
22#include <unistd.h>
23#include <limits.h>
24#endif
25
26#include "udunits.h"
27
28#include "capsBase.h"
29#include "capsAIM.h"
30
31/* OpenCSM Defines & Includes */
32#include "common.h"
33#include "OpenCSM.h"
34
35
36/*@-incondefs@*/
37extern void ut_free(/*@only@*/ ut_unit* const unit);
38/*@+incondefs@*/
39
40extern /*@null@*/ /*@only@*/
41 char *EG_strdup(/*@null@*/ const char *str);
42
43extern int caps_rename(const char *src, const char *dst);
44extern int caps_writeValueObj(capsProblem *problem, capsObject *obj);
45extern void caps_jrnlWrite(int funID, capsProblem *problem, capsObject *obj,
46 int status, int nargs, capsJrnl *args, CAPSLONGunsigned long sNm0,
47 CAPSLONGunsigned long sNum);
48extern int caps_jrnlEnd(capsProblem *problem);
49extern int caps_jrnlRead(int funID, capsProblem *problem, capsObject *obj,
50 int nargs, capsJrnl *args, CAPSLONGunsigned long *sNum, int *stat);
51
52extern int caps_integrateData(const capsObject *vobject, enum capstMethod method,
53 int *rank, double **data, char **units);
54extern int caps_getDataX(const capsObject *vobject, int *npts, int *rank,
55 const double **data, const char **units);
56extern void caps_geomOutSensit(capsProblem *problem, int ipmtr, int irow,
57 int icol);
58extern int caps_build(capsObject *pobject, int *nErr, capsErrs **errors);
59extern void caps_concatErrs(/*@null@*/ capsErrs *errs, capsErrs **errors);
60extern void caps_getAIMerrs(capsAnalysis *analy, int *nErr, capsErrs **errors);
61extern int caps_analysisInfX(const capsObj aobject, char **apath, char **unSys,
62 int *major, int *minor, char **intents,
63 int *nField, char ***fnames, int **ranks,
64 int **fInOut, int *execution, int *status);
65extern int caps_postAnalysiX(capsObject *aobject, int *nErr, capsErrs **errors,
66 int flag);
67extern int caps_unitConvertible(const char *unit1, const char *unit2);
68extern int caps_convert(int count,
69 /*@null@*/ const char *inUnit, double *inVal,
70 /*@null@*/ const char *outUnit, double *outVal);
71extern int caps_unitParse(/*@null@*/ const char *unit);
72extern int caps_execX(capsObject *aobject, int *nErr, capsErrs **errors);
73extern int caps_circularAutoExecs(capsObject *asrc,
74 /*@null@*/ capsObject *aobject);
75extern int caps_transferLinks(capsAnalysis *analysis, int *nErr,
76 capsErrs **errors);
77
78
79int
80caps_checkValueObj(capsObject *object)
81{
82 const char *name = NULL((void*)0);
83 capsValue *value;
84
85 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
86 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
87 if (object->type != VALUE) return CAPS_BADTYPE-306;
88 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
89 value = (capsValue *) object->blind;
90
91 /* check for valid characters in the name */
92 name = object->name;
93 if(name == NULL((void*)0)) {
94 printf(" CAPS Error: Value Object name is NULL\n");
95 return CAPS_NULLNAME-308;
96 }
97 /*
98 len2 = strlen(name);
99 for (j = 0; j < len2; j++) {
100 if ( !(((name[j] >= 'a') && (name[j] <= 'z')) ||
101 ((name[j] >= 'A') && (name[j] <= 'Z')) ||
102 (name[j] == '_') || (name[j] == ':')) )
103 return CAPS_BADNAME;
104 }
105 */
106
107 /* check units */
108 if ((value->type == Pointer) || (value->type == PointerMesh)) {
109 /* Don't look at AIMptr units -- these are programmer defined */
110 if ((value->type == Pointer) && (value->units == NULL((void*)0))) {
111 printf(" CAPS Error: Value '%s' Pointer units is NULL!\n", object->name);
112 return CAPS_UNITERR-320;
113 }
114 } else {
115 if (value->units != NULL((void*)0)) {
116 /* Only double and Strings can have units */
117 if (value->type == Boolean) {
118 printf(" CAPS Error: Value '%s' Integer cannot have units '%s'!\n",
119 object->name, value->units);
120 return CAPS_UNITERR-320;
121 } else if (value->type == Integer) {
122 printf(" CAPS Error: Value '%s' Boolean cannot have units '%s'!\n",
123 object->name, value->units);
124 return CAPS_UNITERR-320;
125 } else if (value->type == Tuple) {
126 printf(" CAPS Error: Value '%s' Tuple cannot have units '%s'!\n",
127 object->name, value->units);
128 return CAPS_UNITERR-320;
129 }
130
131 if ((value->type == Double) ||
132 (value->type == DoubleDeriv)) {
133 if (caps_unitParse(value->units) != CAPS_SUCCESS0) {
134 printf(" CAPS Error: Value '%s' invalid units '%s'!\n",
135 object->name, value->units);
136 return CAPS_UNITERR-320;
137 }
138 }
139 }
140 }
141
142 /* set the length */
143 value->length = value->ncol*value->nrow;
144 if (value->length <= 0 && value->nullVal != IsNull) {
145 printf(" CAPS Error: Value '%s' length <= 0 (nrow = %d, ncol = %d) and not IsNull!\n",
146 object->name, value->nrow, value->ncol);
147 return CAPS_SHAPEERR-322;
148 }
149
150 /* check nullval */
151 if (value->type == Integer) {
152
153 if (value->dim > Scalar && value->length > 1) {
154 if (value->nullVal == NotAllowed && value->vals.integers == NULL((void*)0)) {
155 printf(" CAPS Error: Value '%s' integers is NULL (NotAllowed)!\n",
156 object->name);
157 return CAPS_NULLVALUE-307;
158 }
159 }
160
161 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
162
163 if (value->dim > Scalar && value->length > 1) {
164 if (value->nullVal == NotAllowed && value->vals.reals == NULL((void*)0)) {
165 printf(" CAPS Error: Value '%s' reals is NULL (NotAllowed)!\n",
166 object->name);
167 return CAPS_NULLVALUE-307;
168 }
169 }
170
171 } else if (value->type == String) {
172
173 if (value->nullVal == NotAllowed && value->vals.string == NULL((void*)0)) {
174 printf(" CAPS Error: Value '%s' string is NULL (NotAllowed)!\n",
175 object->name);
176 return CAPS_NULLVALUE-307;
177 }
178 if (value->nullVal != NotAllowed)
179 value->nullVal = (value->vals.string == NULL((void*)0)) ? IsNull : NotNull;
180
181 } else if (value->type == Tuple) {
182
183 if (value->nullVal == NotAllowed && value->vals.tuple == NULL((void*)0)) {
184 printf(" CAPS Error: Value '%s' tuple is NULL (NotAllowed)!\n",
185 object->name);
186 return CAPS_NULLVALUE-307;
187 }
188 if (value->nullVal != NotAllowed)
189 value->nullVal = (value->vals.tuple == NULL((void*)0)) ? IsNull : NotNull;
190
191 if (value->dim != Vector) {
192 printf(" CAPS Error: Value '%s' Tuple dim must be Vector!\n",
193 object->name);
194 return CAPS_SHAPEERR-322;
195 }
196
197 } else if ((value->type == Pointer) || (value->type == PointerMesh)) {
198
199 if (value->nullVal == NotAllowed && value->vals.AIMptr == NULL((void*)0)) {
200 printf(" CAPS Error: Value '%s' AIMptr is NULL (NotAllowed)!\n",
201 object->name);
202 return CAPS_NULLVALUE-307;
203 }
204 if (value->nullVal != NotAllowed)
205 value->nullVal = (value->vals.AIMptr == NULL((void*)0)) ? IsNull : NotNull;
206
207 }
208
209 /* look at shapes */
210 if (value->dim == Scalar) {
211 if (value->length > 1) {
212 printf(" CAPS Error: Value '%s' dim = Scalar and length > 1 (length = %d)!\n",
213 object->name, value->length);
214 return CAPS_SHAPEERR-322;
215 }
216 } else if (value->dim == Vector) {
217 if ((value->ncol != 1) && (value->nrow != 1)) {
218 printf(" CAPS Error: Value '%s' dim = Vector nrow = %d ncol = %d!\n",
219 object->name, value->nrow, value->ncol);
220 return CAPS_SHAPEERR-322;
221 }
222 } else if (value->dim != Array2D) {
223 printf(" CAPS Error: Value '%s' Invalid dim = %d!\n",
224 object->name, value->dim);
225 return CAPS_BADINDEX-304;
226 }
227
228 return CAPS_SUCCESS0;
229}
230
231
232static int
233caps_updateAnalysisOut(capsObject *vobject, const int funID,
234 int *nErr, capsErrs **errors)
235{
236 int i, in, status, major, minor, nField, exec, dirty;
237 int *ranks, *fInOut;
238 char *intents, *apath, *unitSys, **fnames, temp[PATH_MAX4096];
239 capsValue *value, *valu0, *valIn=NULL((void*)0);
240 capsObject *pobject, *aobject;
241 capsProblem *problem;
242 capsAnalysis *analysis;
243 capsErrs *errs = NULL((void*)0);
244
245 *nErr = 0;
246 *errors = NULL((void*)0);
247
248 if (vobject->type != VALUE) return CAPS_BADTYPE-306;
249 if (vobject->subtype != ANALYSISOUT) return CAPS_BADTYPE-306;
250 value = (capsValue *) vobject->blind;
251
252 status = caps_findProblem(vobject, funID, &pobject);
253 if (status != CAPS_SUCCESS0) return status;
254 problem = (capsProblem *) pobject->blind;
255
256 /* do we need to update our value? */
257 aobject = vobject->parent;
258 if (aobject == NULL((void*)0)) return CAPS_NULLOBJ-309;
259 if (aobject->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
260 analysis = (capsAnalysis *) aobject->blind;
261 if (aobject->parent == NULL((void*)0)) return CAPS_NULLOBJ-309;
262
263 /* check to see if analysis is CLEAN, and auto-execute if possible */
264 status = caps_analysisInfX(aobject, &apath, &unitSys, &major, &minor,
265 &intents, &nField, &fnames, &ranks, &fInOut,
266 &exec, &dirty);
267 if (status != CAPS_SUCCESS0) return status;
268 if (dirty > 0) {
269 /* auto execute if available */
270 if ((exec == 2) && (dirty < 5)) {
271 status = caps_execX(aobject, nErr, errors);
272 if (status != CAPS_SUCCESS0) return status;
273 } else {
274 return CAPS_DIRTY-327;
275 }
276 } else if (analysis->reload == 1) {
277
278 /* fill in any values that have links */
279 status = caps_transferLinks(analysis, nErr, errors);
280 if (status != CAPS_SUCCESS0) return status;
281
282 if (analysis->nAnalysisIn > 0)
283 valIn = (capsValue *) analysis->analysisIn[0]->blind;
284/* analysis->info.inPost = 1; */
285 status = aim_PostAnalysis(problem->aimFPTR, analysis->loadName,
286 analysis->instStore, &analysis->info, 1,
287 valIn);
288 analysis->info.inPost = 0;
289
290 if (*nErr != 0) {
291 errs = *errors;
292 *nErr = 0;
293 *errors = NULL((void*)0);
294 }
295 caps_getAIMerrs(analysis, nErr, errors);
296 caps_concatErrs(errs, errors);
297 *nErr = 0;
298 if (*errors != NULL((void*)0)) *nErr = (*errors)->nError;
299 if (status != CAPS_SUCCESS0) {
300 printf(" CAPS Error: PostAnalysis %s (%d) ret = %d (%s -> caps_updateAnalysisOut)!\n",
301 analysis->loadName, analysis->info.instance, status, caps_funID[funID]);
302 return CAPS_BADINIT-338;
303 }
304 analysis->reload = 0;
305 }
306
307 valu0 = (capsValue *) analysis->analysisOut[0]->blind;
308 in = value - valu0;
309 if (vobject->last.sNum < aobject->last.sNum) {
310 if ((value->type == Boolean) || (value->type == Integer)) {
311 if (value->length > 1) {
312 EG_free(value->vals.integers);
313 }
314 value->vals.integers = NULL((void*)0);
315 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
316 if (value->length > 1) {
317 EG_free(value->vals.reals);
318 }
319 value->vals.reals = NULL((void*)0);
320 for (i = 0; i < value->nderiv; i++) {
321 EG_free(value->derivs[i].name);
322 EG_free(value->derivs[i].deriv);
323 }
324 EG_free(value->derivs);
325 value->derivs = NULL((void*)0);
326 value->nderiv = 0;
327 } else if (value->type == String) {
328 EG_free(value->vals.string);
329 value->vals.string = NULL((void*)0);
330 } else if (value->type == Tuple) {
331 caps_freeTuple(value->length, value->vals.tuple);
332 value->vals.tuple = NULL((void*)0);
333 } else if ((value->type != Pointer) && (value->type != PointerMesh)) {
334 return CAPS_BADTYPE-306;
335 }
336 caps_freeOwner(&vobject->last);
337 vobject->last.sNum = 0;
338 status = aim_CalcOutput(problem->aimFPTR, analysis->loadName,
339 analysis->instStore, &analysis->info, in+1, value);
340 caps_getAIMerrs(analysis, nErr, errors);
341 if (status != CAPS_SUCCESS0) return status;
342 status = caps_checkValueObj(analysis->analysisOut[in]);
343 if (status != CAPS_SUCCESS0) {
344 snprintf(temp, PATH_MAX4096, "'%s' CalcOutput Check Value %d (%s)",
345 analysis->loadName, status, caps_funID[funID]);
346 caps_makeSimpleErr(analysis->analysisOut[in], CERROR, temp,
347 NULL((void*)0), NULL((void*)0), errors);
348 if (*errors != NULL((void*)0)) *nErr = (*errors)->nError;
349 return status;
350 }
351 vobject->last.sNum = aobject->last.sNum;
352 status = caps_addHistory(vobject, problem);
353 if (status != CAPS_SUCCESS0)
354 printf(" CAPS Warning: caps_addHistory = %d (%s)\n",
355 status, caps_funID[funID]);
356 status = caps_writeValueObj(problem, analysis->analysisOut[in]);
357 if (status != CAPS_SUCCESS0)
358 printf(" CAPS Warning: caps_writeValueObj = %d (%s)\n",
359 status, caps_funID[funID]);
360 }
361
362 return CAPS_SUCCESS0;
363}
364
365
366static int
367caps_getValuX(capsObject *object, enum capsvType *type, int *nrow, int *ncol,
368 const void **data, const int **partial, const char **units,
369 int *nErr, capsErrs **errors)
370{
371 int status;
372 capsValue *value;
373 capsObject *pobject, *source, *last;
374 capsProblem *problem;
375
376 *nErr = 0;
377 *errors = NULL((void*)0);
378 status = caps_findProblem(object, 9999, &pobject);
379 if (status != CAPS_SUCCESS0) return status;
380 problem = (capsProblem *) pobject->blind;
381
382 source = object;
383 do {
384 if (source->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
385 if (source->type != VALUE) return CAPS_BADTYPE-306;
386 if (source->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
387 value = (capsValue *) source->blind;
388 if (value->link == object) return CAPS_CIRCULARLINK-319;
389 last = source;
390 source = value->link;
391 } while (value->link != NULL((void*)0));
392
393 /* do we need to update our value? */
394 if (problem->dbFlag == 0)
395 if (last->subtype == ANALYSISOUT) {
396 status = caps_updateAnalysisOut(last, CAPS_GETVALUE80, nErr, errors);
397 if (status != CAPS_SUCCESS0) return status;
398 } else if (last->subtype == GEOMETRYOUT) {
399 /* make sure geometry is up-to-date */
400 status = caps_build(pobject, nErr, errors);
401 if ((status != CAPS_SUCCESS0) && (status != CAPS_CLEAN-336)) return status;
402 }
403
404 *type = value->type;
405 *nrow = value->nrow;
406 *ncol = value->ncol;
407 *partial = value->partial;
408 *units = value->units;
409 if (value->nullVal == IsNull) *nrow = *ncol = 0;
410
411 /* always return nrow > 1 for Vector */
412 if (value->dim == Vector && value->ncol > 1) {
413 *nrow = value->ncol;
414 *ncol = value->nrow;
415 }
416
417 if (data != NULL((void*)0)) {
418 *data = NULL((void*)0);
419 if (value->nullVal != IsNull) {
420 if ((value->type == Boolean) || (value->type == Integer)) {
421 if (value->length == 1) {
422 *data = &value->vals.integer;
423 } else {
424 *data = value->vals.integers;
425 }
426 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
427 if (value->length == 1) {
428 *data = &value->vals.real;
429 } else {
430 *data = value->vals.reals;
431 }
432 } else if (value->type == String) {
433 *data = value->vals.string;
434 } else if (value->type == Tuple) {
435 *data = value->vals.tuple;
436 } else {
437 *data = value->vals.AIMptr;
438 }
439 }
440 }
441
442 return CAPS_SUCCESS0;
443}
444
445
446int
447caps_getValue(capsObject *object, enum capsvType *type, int *nrow, int *ncol,
448 const void **data, const int **partial, const char **units,
449 int *nErr, capsErrs **errors)
450{
451 int i, stat, ret, vlen;
452 const char *string;
453 CAPSLONGunsigned long sNum;
454 capsObject *pobject;
455 capsProblem *problem;
456 capsValue *value;
457 capsJrnl args[8];
458 enum capsvType itype;
459 size_t len;
460
461 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
462 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
463 *nErr = 0;
464 *errors = NULL((void*)0);
465 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
466 if (nrow == NULL((void*)0)) return CAPS_NULLVALUE-307;
467 if (ncol == NULL((void*)0)) return CAPS_NULLVALUE-307;
468 if (partial == NULL((void*)0)) return CAPS_NULLVALUE-307;
469 if (units == NULL((void*)0)) return CAPS_NULLVALUE-307;
470 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
471 if (object->type != VALUE) return CAPS_BADTYPE-306;
472 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
473 value = (capsValue *) object->blind;
474 stat = caps_findProblem(object, CAPS_GETVALUE80, &pobject);
475 if (stat != CAPS_SUCCESS0) return stat;
476 problem = (capsProblem *) pobject->blind;
477
478 /* just return the values if in debug mode */
479 if (problem->dbFlag == 1) {
480 ret = caps_getValuX(object, type, nrow, ncol, data, partial, units,
481 nErr, errors);
482 *nErr = 0;
483 if (*errors != NULL((void*)0)) *nErr = (*errors)->nError;
484 return ret;
485 }
486
487 args[0].type = jInteger;
488 args[1].type = jInteger;
489 args[2].type = jInteger;
490 args[3].type = jPointer;
491 args[4].type = jPointer;
492 args[5].type = jString;
493 args[6].type = jInteger;
494 args[7].type = jErr;
495 if (value->type == Tuple) args[3].type = jTuple;
496 stat = caps_jrnlRead(CAPS_GETVALUE80, problem, object, 8, args, &sNum,
497 &ret);
498 if (stat == CAPS_JOURNALERR-343) return stat;
499 if (stat == CAPS_JOURNAL-342) {
500 *type = args[0].members.integer;
501 *nrow = args[1].members.integer;
502 *ncol = args[2].members.integer;
503 if (value->type == Tuple) {
504 *data = args[3].members.tuple;
505 } else {
506 *data = args[3].members.pointer;
507 }
508 *partial = args[4].members.pointer;
509 *units = args[5].members.string;
510 *nErr = args[6].members.integer;
511 *errors = args[7].members.errs;
512 return ret;
513 }
514
515 itype = Pointer;
516 *nrow = *ncol = 0;
517 *data = NULL((void*)0);
518 *partial = NULL((void*)0);
519 *units = NULL((void*)0);
520 if (ret == CAPS_SUCCESS0) {
521 ret = caps_getValuX(object, &itype, nrow, ncol, data, partial, units,
522 nErr, errors);
523 *nErr = 0;
524 if (*errors != NULL((void*)0)) *nErr = (*errors)->nError;
525 }
526 args[0].members.integer = itype;
527 args[1].members.integer = *nrow;
528 args[2].members.integer = *ncol;
529 if (itype == Tuple) args[3].members.tuple = (void *) *data;
530/*@-kepttrans@*/
531 if (itype != Tuple) args[3].members.pointer = (void *) *data;
532/*@+kepttrans@*/
533 args[4].members.pointer = (void *) *partial;
534 args[5].members.string = (void *) *units;
535 args[6].members.integer = *nErr;
536 args[7].members.errs = *errors;
537 args[3].length = 0;
538 args[3].num = 0;
539 args[4].length = 0;
540 vlen = *nrow;
541 vlen *= *ncol;
542 if (*data != NULL((void*)0)) {
543 if (itype == Tuple) {
544 args[3].num = vlen;
545 } else {
546 len = sizeof(char *);
547 if ((itype == Integer) || (itype == Boolean)) {
548 len = vlen*sizeof(int);
549 } else if ((itype == Double) || (itype == DoubleDeriv)) {
550 len = vlen*sizeof(double);
551 } else if (itype == String) {
552 string = (char *) *data;
553 if (vlen == 1) {
554 len = (strlen(string)+1)*sizeof(char);
555 } else {
556 len = 0;
557 for (i = 0; i < vlen; i++)
558 len += strlen(string + len) + 1;
559 len *= sizeof(char);
560 }
561 }
562 args[3].length = len;
563 }
564 }
565 if (*partial != NULL((void*)0)) {
566 len = *nrow;
567 len *= *ncol*sizeof(int);
568 args[4].length = len;
569 }
570 *type = itype;
571 caps_jrnlWrite(CAPS_GETVALUE80, problem, object, ret, 8, args, sNum,
572 problem->sNum);
573
574 return ret;
575}
576
577
578int
579caps_makeValueX(capsObject *pobject, const char *vname, enum capssType stype,
580 enum capsvType vtype, int nrow, int ncol, const void *data,
581 /*@null@*/ int *partial, /*@null@*/ const char *units,
582 capsObject **vobj)
583{
584 int status, i, vlen;
585 char filename[PATH_MAX4096], temp[PATH_MAX4096];
586 capsObject *object, **tmp;
587 capsProblem *problem;
588 capsValue *value;
589 FILE *fp;
590
591 vlen = ncol*nrow;
592 problem = (capsProblem *) pobject->blind;
593
594 status = caps_makeVal(vtype, vlen, data, &value);
595 if (status != CAPS_SUCCESS0) return status;
596 value->nrow = nrow;
597 value->ncol = ncol;
598 value->dim = Scalar;
599 if ((nrow > 1) || (ncol > 1)) value->dim = Vector;
600 if ((nrow > 1) && (ncol > 1)) value->dim = Array2D;
601
602 /* set partial if applicable */
603 if (partial != NULL((void*)0)) {
604 value->partial = (int*) EG_alloc(vlen*sizeof(int));
605 if (value->partial == NULL((void*)0)) {
606 if (value->length != 1) {
607 if (value->type == Integer) {
608 EG_free(value->vals.integers);
609 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
610 EG_free(value->vals.reals);
611 } else if (value->type == String) {
612 EG_free(value->vals.string);
613 } else if (value->type == Tuple) {
614 caps_freeTuple(value->length, value->vals.tuple);
615 }
616 }
617 EG_free(value);
618 return EGADS_MALLOC-4;
619 }
620 for (i = 0; i < vlen; i++) value->partial[i] = partial[i];
621 value->nullVal = IsPartial;
622 }
623
624 /* make the object */
625 status = caps_makeObject(&object);
626 if (status != CAPS_SUCCESS0) {
627 if (value->length != 1) {
628 if (value->type == Integer) {
629 EG_free(value->vals.integers);
630 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
631 EG_free(value->vals.reals);
632 } else if (value->type == String) {
633 EG_free(value->vals.string);
634 } else if (value->type == Tuple) {
635 caps_freeTuple(value->length, value->vals.tuple);
636 }
637 }
638 EG_free(value->partial);
639 EG_free(value);
640 return status;
641 }
642 object->parent = pobject;
643
644 /* save away the object in the problem object */
645 if (stype == PARAMETER) {
646 value->index = problem->nParam + 1;
647 if (problem->params == NULL((void*)0)) {
648 problem->params = (capsObject **) EG_alloc(sizeof(capsObject *));
649 if (problem->params == NULL((void*)0)) {
650 if (value->length != 1) {
651 if (value->type == Integer) {
652 EG_free(value->vals.integers);
653 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
654 EG_free(value->vals.reals);
655 } else if (value->type == String) {
656 EG_free(value->vals.string);
657 } else if (value->type == Tuple) {
658 caps_freeTuple(value->length, value->vals.tuple);
659 }
660 }
661 EG_free(value->partial);
662 EG_free(value);
663 EG_free(object);
664 return EGADS_MALLOC-4;
665 }
666 } else {
667 tmp = (capsObject **) EG_reall( problem->params,
668 (problem->nParam+1)*sizeof(capsObject *));
669 if (tmp == NULL((void*)0)) {
670 if (value->length != 1) {
671 if (value->type == Integer) {
672 EG_free(value->vals.integers);
673 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
674 EG_free(value->vals.reals);
675 } else if (value->type == String) {
676 EG_free(value->vals.string);
677 } else if (value->type == Tuple) {
678 caps_freeTuple(value->length, value->vals.tuple);
679 }
680 }
681 EG_free(value->partial);
682 EG_free(value);
683 EG_free(object);
684 return EGADS_MALLOC-4;
685 }
686 problem->params = tmp;
687 }
688 problem->params[problem->nParam] = object;
689 problem->nParam += 1;
690 } else {
691 value->index = problem->nUser + 1;
692 if (problem->users == NULL((void*)0)) {
693 problem->users = (capsObject **) EG_alloc(sizeof(capsObject *));
694 if (problem->users == NULL((void*)0)) {
695 if (value->length != 1) {
696 if (value->type == Integer) {
697 EG_free(value->vals.integers);
698 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
699 EG_free(value->vals.reals);
700 } else if (value->type == String) {
701 EG_free(value->vals.string);
702 } else if (value->type == Tuple) {
703 caps_freeTuple(value->length, value->vals.tuple);
704 }
705 }
706 EG_free(value->partial);
707 EG_free(value);
708 EG_free(object);
709 return EGADS_MALLOC-4;
710 }
711 } else {
712 tmp = (capsObject **) EG_reall( problem->users,
713 (problem->nUser+1)*sizeof(capsObject *));
714 if (tmp == NULL((void*)0)) {
715 if (value->length != 1) {
716 if (value->type == Integer) {
717 EG_free(value->vals.integers);
718 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
719 EG_free(value->vals.reals);
720 } else if (value->type == String) {
721 EG_free(value->vals.string);
722 } else if (value->type == Tuple) {
723 caps_freeTuple(value->length, value->vals.tuple);
724 }
725 }
726 EG_free(value->partial);
727 EG_free(value);
728 EG_free(object);
729 return EGADS_MALLOC-4;
730 }
731 problem->users = tmp;
732 }
733 problem->users[problem->nUser] = object;
734 problem->nUser += 1;
735 }
736 problem->sNum += 1;
737 object->last.sNum = problem->sNum;
738
739 /* finish the object off */
740 if ((units != NULL((void*)0)) &&
741 (strlen(units) > 0)) value->units = EG_strdup(units);
742 object->name = EG_strdup(vname);
743 object->type = VALUE;
744 object->subtype = stype;
745 object->blind = value;
746/*@-kepttrans@*/
747 object->parent = pobject;
748/*@+kepttrans@*/
749
750 /* register for restart */
751#ifdef WIN32
752 snprintf(filename, PATH_MAX4096, "%s\\capsRestart\\param.txt", problem->root);
753 snprintf(temp, PATH_MAX4096, "%s\\capsRestart\\xxTempxx", problem->root);
754#else
755 snprintf(filename, PATH_MAX4096, "%s/capsRestart/param.txt", problem->root);
756 snprintf(temp, PATH_MAX4096, "%s/capsRestart/xxTempxx", problem->root);
757#endif
758 fp = fopen(temp, "w");
759 if (fp == NULL((void*)0)) {
760 printf(" CAPS Warning: Cannot open %s (caps_makeValue)\n", filename);
761 } else {
762 fprintf(fp, "%d %d\n", problem->nParam, problem->nUser);
763 if (problem->params != NULL((void*)0))
764 for (i = 0; i < problem->nParam; i++)
765 fprintf(fp, "%s\n", problem->params[i]->name);
766 fclose(fp);
767 status = caps_rename(temp, filename);
768 if (status != CAPS_SUCCESS0)
769 printf(" CAPS Warning: Cannot rename %s!\n", filename);
770 }
771 status = caps_writeValueObj(problem, object);
772 if (status != CAPS_SUCCESS0)
773 printf(" CAPS Warning: caps_writeValueObj = %d (caps_makeValue)\n",
774 status);
775
776 *vobj = object;
777
778 return CAPS_SUCCESS0;
779}
780
781
782int
783caps_makeValue(capsObject *pobject, const char *vname, enum capssType stype,
784 enum capsvType vtype, int nrow, int ncol, const void *data,
785 /*@null@*/ int *partial, /*@null@*/ const char *units,
786 capsObject **vobj)
787{
788 int i, stat, ret, vlen;
789 CAPSLONGunsigned long sNum;
790 capsProblem *problem;
791 ut_unit *utunit;
792 capsJrnl args[1];
793
794 if (pobject == NULL((void*)0)) return CAPS_NULLOBJ-309;
795 if (vobj == NULL((void*)0)) return CAPS_NULLOBJ-309;
796 *vobj = NULL((void*)0);
797 if (pobject->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
798 if (pobject->type != PROBLEM) return CAPS_BADTYPE-306;
799 if (pobject->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
800 if (vname == NULL((void*)0)) return CAPS_NULLNAME-308;
801 if ((stype != PARAMETER) && (stype != USER)) return CAPS_BADTYPE-306;
802 if (!((vtype == Double) || (vtype == DoubleDeriv) || (vtype == String))
803 && (units != NULL((void*)0))) return CAPS_UNITERR-320;
804 vlen = ncol*nrow;
805 if (vlen <= 0) return CAPS_BADINDEX-304;
806 problem = (capsProblem *) pobject->blind;
807 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
808
809 args[0].type = jObject;
810 stat = caps_jrnlRead(CAPS_MAKEVALUE81, problem, *vobj, 1, args, &sNum,
811 &ret);
812 if (stat == CAPS_JOURNALERR-343) return stat;
813 if (stat == CAPS_JOURNAL-342) {
814 if (ret == CAPS_SUCCESS0) *vobj = args[0].members.obj;
815 return ret;
816 }
817
818 /* check for unique name */
819 ret = CAPS_SUCCESS0;
820 if ((stype == PARAMETER) && (problem->params != NULL((void*)0)))
821 for (i = 0; i < problem->nParam; i++) {
822 if (problem->params[i] == NULL((void*)0)) continue;
823 if (problem->params[i]->name == NULL((void*)0)) continue;
824 if (strcmp(problem->params[i]->name, vname) == 0) ret = CAPS_BADNAME-317;
825 }
826
827 /* check the units */
828 if ((units != NULL((void*)0)) && (ret == CAPS_SUCCESS0)) {
829 utunit = ut_parse((ut_system *) problem->utsystem, units, UT_ASCII);
830 if (utunit == NULL((void*)0)) ret = CAPS_UNITERR-320;
831 ut_free(utunit);
832 }
833
834 sNum = problem->sNum;
835 if (ret == CAPS_SUCCESS0)
836 ret = caps_makeValueX(pobject, vname, stype, vtype, nrow, ncol, data,
837 partial, units, vobj);
838 args[0].members.obj = *vobj;
839 caps_jrnlWrite(CAPS_MAKEVALUE81, problem, *vobj, ret, 1, args, sNum,
840 problem->sNum);
841
842 return ret;
843}
844
845
846static int
847caps_setValuX(capsObject *object, enum capsvType vtype, int nrow, int ncol,
848 const void *data, /*@null@*/ const int *partial,
849 /*@null@*/ const char *units, int *nErr, capsErrs **errors)
850{
851 int i, j, k, n, vlen, slen=0, status;
852 int *ints = NULL((void*)0);
853 double *reals = NULL((void*)0);
854 char *str = NULL((void*)0);
855 capsTuple *tuple = NULL((void*)0);
856 capsObject *pobject, *source, *last;
857 capsValue *value;
858 capsProblem *problem;
859
860 *nErr = 0;
861 *errors = NULL((void*)0);
862 value = (capsValue *) object->blind;
863 vlen = nrow*ncol;
864 status = caps_unitConvertible(units, value->units);
865 if (status != CAPS_SUCCESS0) return status;
1
Assuming 'status' is equal to CAPS_SUCCESS
2
Taking false branch
866
867 status = caps_findProblem(object, 9999, &pobject);
868 if (status != CAPS_SUCCESS0) return status;
3
Assuming 'status' is equal to CAPS_SUCCESS
4
Taking false branch
869 problem = (capsProblem *) pobject->blind;
870
871 if (data == NULL((void*)0)) {
5
Assuming 'data' is equal to NULL
6
Taking true branch
872 if(value->lfixed == Change) vlen = 0;
7
Assuming field 'lfixed' is not equal to Change
8
Taking false branch
873 else vlen = value->length;
874 }
875
876 if ((value->type != vtype) && (data != NULL((void*)0))) {
9
Assuming 'vtype' is equal to field 'type'
877 if (!(((value->type == Double) || (value->type == DoubleDeriv)) &&
878 ((vtype == Integer) || (vtype == Boolean))))
879 return CAPS_BADTYPE-306;
880 }
881 if (value->nullVal == IsNull ||
10
Assuming field 'nullVal' is not equal to IsNull
12
Taking false branch
882 value->nullVal == IsPartial) value->nullVal = NotNull;
11
Assuming field 'nullVal' is not equal to IsPartial
883
884 /* are we in range? */
885 if (value->type == Integer) {
13
Assuming field 'type' is equal to Integer
14
Taking true branch
886 if (value->limits.ilims[0] != value->limits.ilims[1])
15
Assuming the condition is true
16
Taking true branch
887 if (vtype == Integer) {
17
Assuming 'vtype' is not equal to Integer
18
Taking false branch
888 ints = (int *) data;
889 for (i = 0; i < vlen; i++)
890 if ((ints[i] < value->limits.ilims[0]) ||
891 (ints[i] > value->limits.ilims[1])) return CAPS_RANGEERR-326;
892 } else {
893 reals = (double *) data;
19
Null pointer value stored to 'reals'
894 for (i = 0; i < vlen; i++)
20
Assuming 'i' is < 'vlen'
21
Loop condition is true. Entering loop body
895 if ((reals[i] < value->limits.ilims[0]) ||
22
Array access (from variable 'reals') results in a null pointer dereference
896 (reals[i] > value->limits.ilims[1])) return CAPS_RANGEERR-326;
897 }
898 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
899 if (value->limits.dlims[0] != value->limits.dlims[1])
900 if (vtype == Integer) {
901 ints = (int *) data;
902 for (i = 0; i < vlen; i++)
903 if ((ints[i] < value->limits.dlims[0]) ||
904 (ints[i] > value->limits.dlims[1])) return CAPS_RANGEERR-326;
905 } else {
906 reals = (double *) data;
907 for (i = 0; i < vlen; i++)
908 if ((reals[i] < value->limits.dlims[0]) ||
909 (reals[i] > value->limits.dlims[1])) return CAPS_RANGEERR-326;
910 }
911 }
912
913 /* check for uniqueness in tuple names */
914 if ((vtype == Tuple) && (data != NULL((void*)0))) {
915 tuple = (capsTuple *) data;
916 for (i = 0; i < vlen; i++)
917 for (j = i+1; j < vlen; j++)
918 if (strcmp(tuple[i].name, tuple[j].name) == 0)
919 return CAPS_BADVALUE-311;
920 }
921
922 /* remove any existing memory */
923 if (vlen != value->length) {
924 if ((value->lfixed == Fixed) && (value->type != String) &&
925 (value->type != Pointer) && (value->type != Tuple) &&
926 (value->type != PointerMesh)) return CAPS_SHAPEERR-322;
927 if ((value->type == Boolean) || (value->type == Integer)) {
928 if (vlen > 1) {
929 ints = (int *) EG_alloc(vlen*sizeof(int));
930 if (ints == NULL((void*)0)) return EGADS_MALLOC-4;
931 }
932 if (value->length > 1) EG_free(value->vals.integers);
933 if (ints != NULL((void*)0)) value->vals.integers = ints;
934 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
935 if (vlen > 1) {
936 reals = (double *) EG_alloc(vlen*sizeof(double));
937 if (reals == NULL((void*)0)) return EGADS_MALLOC-4;
938 }
939 if (value->length > 1) EG_free(value->vals.reals);
940 if (reals != NULL((void*)0)) value->vals.reals = reals;
941 } else if (value->type == Tuple) {
942 if (vlen > 0) {
943 status = caps_makeTuple(vlen, &tuple);
944 if ((status != CAPS_SUCCESS0) || (tuple == NULL((void*)0))) {
945 if (tuple == NULL((void*)0)) status = CAPS_NULLVALUE-307;
946 return status;
947 }
948 }
949 caps_freeTuple(value->length, value->vals.tuple);
950 value->vals.tuple = tuple;
951 }
952
953 if ((value->nullVal == IsPartial) || (partial != NULL((void*)0))) {
954 ints = (int *) EG_alloc(vlen*sizeof(int));
955 if (ints == NULL((void*)0)) return EGADS_MALLOC-4;
956 EG_free(value->partial);
957 value->partial = ints;
958 for (i = 0; i < vlen; i++) value->partial[i] = NotNull;
959 value->nullVal = IsPartial;
960 }
961
962 value->length = vlen;
963 } else {
964 if (value->type == Tuple) {
965 status = caps_makeTuple(vlen, &tuple);
966 if ((status != CAPS_SUCCESS0) || (tuple == NULL((void*)0))) {
967 if (tuple == NULL((void*)0)) status = CAPS_NULLVALUE-307;
968 return status;
969 }
970 caps_freeTuple(value->length, value->vals.tuple);
971 value->vals.tuple = tuple;
972 }
973 }
974
975 /* set the values */
976 if (data == NULL((void*)0)) {
977 value->nullVal = IsNull;
978 } else {
979 if ((value->type == Boolean) || (value->type == Integer)) {
980 ints = (int *) data;
981 if (vlen == 1) {
982 value->vals.integer = ints[0];
983 } else {
984 for (i = 0; i < vlen; i++) value->vals.integers[i] = ints[i];
985 }
986 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
987 if ((vtype == Double) || (vtype == DoubleDeriv)) {
988 reals = (double *) data;
989 if (vlen == 1) {
990 value->vals.real = reals[0];
991 reals = &value->vals.real;
992 } else {
993 for (i = 0; i < vlen; i++) value->vals.reals[i] = reals[i];
994 reals = value->vals.reals;
995 }
996 } else {
997 ints = (int *) data;
998 if (vlen == 1) {
999 value->vals.real = ints[0];
1000 reals = &value->vals.real;
1001 } else {
1002 for (i = 0; i < vlen; i++) value->vals.reals[i] = ints[i];
1003 reals = value->vals.reals;
1004 }
1005 }
1006 status = caps_convert(vlen, units, reals, value->units, reals);
1007 if (status != CAPS_SUCCESS0) return status;
1008 } else if (value->type == String) {
1009 /* always re-allocate strings */
1010 EG_free(value->vals.string);
1011 value->vals.string = NULL((void*)0);
1012 str = (char *) data;
1013 for (slen = i = 0; i < vlen; i++)
1014 slen += strlen(str + slen)+1;
1015 value->vals.string = (char *) EG_alloc(slen*sizeof(char));
1016 if (value->vals.string == NULL((void*)0)) return EGADS_MALLOC-4;
1017 for (i = 0; i < slen; i++) value->vals.string[i] = str[i];
1018 } else if (value->type == Tuple) {
1019 tuple = (capsTuple *) data;
1020 for (i = 0; i < vlen; i++) {
1021 value->vals.tuple[i].name = EG_strdup(tuple[i].name);
1022 value->vals.tuple[i].value = EG_strdup(tuple[i].value);
1023 if ((tuple[i].name != NULL((void*)0)) &&
1024 (value->vals.tuple[i].name == NULL((void*)0))) return EGADS_MALLOC-4;
1025 if ((tuple[i].value != NULL((void*)0)) &&
1026 (value->vals.tuple[i].value == NULL((void*)0))) return EGADS_MALLOC-4;
1027 }
1028 } else {
1029 /*@-kepttrans@*/
1030 value->vals.AIMptr = (void *) data;
1031 /*@+kepttrans@*/
1032 }
1033 if (partial != NULL((void*)0)) {
1034 if (value->partial == NULL((void*)0)) {
1035 ints = (int *) EG_alloc(vlen*sizeof(int));
1036 if (ints == NULL((void*)0)) return EGADS_MALLOC-4;
1037 value->partial = ints;
1038 }
1039 for (i = 0; i < vlen; i++) value->partial[i] = partial[i];
1040 value->nullVal = IsPartial;
1041 } else {
1042 EG_free(value->partial);
1043 value->partial = NULL((void*)0);
1044 }
1045 }
1046
1047 if (value->dim == Vector) {
1048 if (value->ncol == 1) value->nrow = vlen;
1049 else value->ncol = vlen;
1050 } else {
1051 value->nrow = nrow;
1052 value->ncol = ncol;
1053 }
1054
1055 if (object->subtype != USER) {
1056 caps_freeOwner(&object->last);
1057 problem->sNum += 1;
1058 object->last.sNum = problem->sNum;
1059 status = caps_addHistory(object, problem);
1060 if (status != CAPS_SUCCESS0)
1061 printf(" CAPS Warning: caps_addHistory = %d (caps_setValue)\n", status);
1062 }
1063
1064 /* apply GeometryIn changes now -- direct and linkages */
1065 if (object->subtype == GEOMETRYIN) {
1066 if (vlen == 1) {
1067 reals = &value->vals.real;
1068 } else {
1069 reals = value->vals.reals;
1070 }
1071 for (n = k = 0; k < value->nrow; k++)
1072 for (j = 0; j < value->ncol; j++, n++) {
1073 if (value->partial != NULL((void*)0)) {
1074 status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1,
1075 value->partial[n] == NotNull ? reals[n] : -HUGEQ99999999.0);
1076 } else {
1077 status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1,
1078 reals[n]);
1079 }
1080 if (status != SUCCESS0) {
1081 printf(" CAPS Error: Cant change %s[%d,%d] = %d (caps_setValue)!\n",
1082 object->name, k+1, j+1, status);
1083 return CAPS_BADVALUE-311;
1084 }
1085 }
1086 } else {
1087 for (i = 0; i < problem->nGeomIn; i++) {
1088 source = problem->geomIn[i];
1089 last = NULL((void*)0);
1090 do {
1091 if (source->magicnumber != CAPSMAGIC1234321) break;
1092 if (source->type != VALUE) break;
1093 if (source->blind == NULL((void*)0)) break;
1094 value = (capsValue *) source->blind;
1095 if (value->link == problem->geomIn[i]) break;
1096 last = source;
1097 source = value->link;
1098 } while (value->link != NULL((void*)0));
1099 if (last != object) continue;
1100 /* we hit our object from a GeometryIn link */
1101 source = problem->geomIn[i];
1102 value = (capsValue *) source->blind;
1103 if ((value->nrow != nrow) || (value->ncol != ncol)) {
1104 printf(" CAPS Warning: Shape problem with link %s %s (caps_setValue)!\n",
1105 object->name, source->name);
1106 continue;
1107 }
1108 if ((vtype == Double) || (vtype == DoubleDeriv)) {
1109 reals = (double *) data;
1110 if (vlen == 1) {
1111 value->vals.real = reals[0];
1112 reals = &value->vals.real;
1113 } else {
1114 for (i = 0; i < vlen; i++) value->vals.reals[i] = reals[i];
1115 reals = value->vals.reals;
1116 }
1117 } else {
1118 ints = (int *) data;
1119 if (vlen == 1) {
1120 value->vals.real = ints[0];
1121 reals = &value->vals.real;
1122 } else {
1123 for (i = 0; i < vlen; i++) value->vals.reals[i] = ints[i];
1124 reals = value->vals.reals;
1125 }
1126 }
1127 status = caps_convert(vlen, units, reals, value->units, reals);
1128 if (status != CAPS_SUCCESS0) return status;
1129 for (n = k = 0; k < nrow; k++)
1130 for (j = 0; j < ncol; j++, n++) {
1131 if (value->nullVal == IsPartial) {
1132 status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1,
1133 value->partial[n] == NotNull ? reals[n] : -HUGEQ99999999.0);
1134 } else {
1135 status = ocsmSetValuD(problem->modl, value->pIndex, k+1, j+1,
1136 reals[n]);
1137 }
1138 if (status != SUCCESS0) {
1139 printf(" CAPS Error: Cant change %s[%d,%d] = %d (caps_setValue)!\n",
1140 object->name, k+1, j+1, status);
1141 return CAPS_BADVALUE-311;
1142 }
1143 }
1144 caps_freeOwner(&source->last);
1145 source->last = object->last;
1146 source->last.pname = EG_strdup(object->last.pname);
1147 source->last.pID = EG_strdup(object->last.pID);
1148 source->last.user = EG_strdup(object->last.user);
1149 }
1150 }
1151
1152 /* register the change for restarts */
1153 if (object->subtype != USER) {
1154 status = caps_writeValueObj(problem, object);
1155 if (status != CAPS_SUCCESS0)
1156 printf(" CAPS Warning: caps_writeValueObj = %d (caps_setValue)\n",
1157 status);
1158 }
1159
1160 return CAPS_SUCCESS0;
1161}
1162
1163
1164int
1165caps_setValue(capsObject *object, enum capsvType vtype, int nrow, int ncol,
1166 /*@null@*/ const void *data, /*@null@*/ const int *partial,
1167 /*@null@*/ const char *units, int *nErr, capsErrs **errors)
1168{
1169 int i, stat, ret, vlen;
1170 CAPSLONGunsigned long sNum;
1171 capsObject *pobject;
1172 capsValue *value;
1173 capsProblem *problem;
1174 capsJrnl args[2];
1175
1176 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1177 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1178 *nErr = 0;
1179 *errors = NULL((void*)0);
1180 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1181 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1182 if (object->type != VALUE) return CAPS_BADTYPE-306;
1183 if (object->subtype == GEOMETRYOUT) return CAPS_BADTYPE-306;
1184 if (object->subtype == ANALYSISOUT) return CAPS_BADTYPE-306;
1185 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1186 value = (capsValue *) object->blind;
1187 if (object->subtype == GEOMETRYIN)
1188 if (value->gInType == 2) return CAPS_READONLYERR-315;
1189 if (value->link != NULL((void*)0)) return CAPS_LINKERR-323;
1190 if (data == NULL((void*)0)) {
1191 if (value->nullVal == NotAllowed) return CAPS_NULLVALUE-307;
1192 } else {
1193 vlen = nrow*ncol;
1194 if (vlen <= 0) return CAPS_RANGEERR-326;
1195 if (value->sfixed == Fixed) {
1196 if (value->dim == Scalar) {
1197 if (vlen > 1) return CAPS_SHAPEERR-322;
1198 } else if (value->dim == Vector) {
1199 if ((ncol != 1) && (nrow != 1)) return CAPS_SHAPEERR-322;
1200 }
1201 }
1202 if ((value->lfixed == Fixed) && (vlen != value->length))
1203 return CAPS_SHAPEERR-322;
1204 if (partial != NULL((void*)0)) {
1205 for (i = 0; i < vlen; i++)
1206 if (!(partial[i] == NotNull ||
1207 partial[i] == IsNull)) return CAPS_NULLVALUE-307;
1208 }
1209 }
1210
1211 stat = caps_findProblem(object, CAPS_SETVALUE82, &pobject);
1212 if (stat != CAPS_SUCCESS0) return stat;
1213 if (( object->subtype == GEOMETRYIN) &&
1214 (pobject->subtype == STATIC )) return CAPS_READONLYERR-315;
1215 problem = (capsProblem *) pobject->blind;
1216 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1217
1218 args[0].type = jInteger;
1219 args[1].type = jErr;
1220 stat = caps_jrnlRead(CAPS_SETVALUE82, problem, object, 2, args, &sNum,
1221 &ret);
1222 if (stat == CAPS_JOURNALERR-343) return stat;
1223 if (stat == CAPS_JOURNAL-342) {
1224 *nErr = args[0].members.integer;
1225 *errors = args[1].members.errs;
1226 return ret;
1227 }
1228
1229 sNum = problem->sNum;
1230 ret = caps_setValuX(object, vtype, nrow, ncol, data, partial, units, nErr,
1231 errors);
1232 args[0].members.integer = *nErr;
1233 args[1].members.errs = *errors;
1234 caps_jrnlWrite(CAPS_SETVALUE82, problem, object, ret, 2, args, sNum,
1235 problem->sNum);
1236
1237 return ret;
1238}
1239
1240
1241int
1242caps_getLimits(const capsObj object, enum capsvType *vtype, const void **limits,
1243 const char **units)
1244{
1245 int status, ret;
1246 CAPSLONGunsigned long sNum;
1247 capsObject *pobject;
1248 capsValue *value;
1249 capsProblem *problem;
1250 capsJrnl args[3];
1251
1252 if (limits == NULL((void*)0)) return CAPS_NULLVALUE-307;
1253 *limits = NULL((void*)0);
1254 if (units == NULL((void*)0)) return CAPS_NULLVALUE-307;
1255 *units = NULL((void*)0);
1256 if (vtype == NULL((void*)0)) return CAPS_NULLVALUE-307;
1257 *vtype = 0;
1258
1259 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1260 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1261 if (object->type != VALUE) return CAPS_BADTYPE-306;
1262 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1263 value = (capsValue *) object->blind;
1264 if ((value->type != Integer) && (value->type != Double) &&
1265 (value->type != DoubleDeriv)) return CAPS_BADTYPE-306;
1266
1267 status = caps_findProblem(object, CAPS_GETLIMITS83, &pobject);
1268 if (status != CAPS_SUCCESS0) return status;
1269 problem = (capsProblem *) pobject->blind;
1270
1271 args[0].type = jInteger;
1272 args[1].type = jPointer;
1273 args[2].type = jString;
1274 if (problem->dbFlag == 0) {
1275 status = caps_jrnlRead(CAPS_GETLIMITS83, problem, object, 3, args, &sNum,
1276 &ret);
1277 if (status == CAPS_JOURNALERR-343) return status;
1278 if (status == CAPS_JOURNAL-342) {
1279 *vtype = args[0].members.integer;
1280 *limits = args[1].members.pointer;
1281 *units = args[2].members.string;
1282 return ret;
1283 }
1284 }
1285
1286 *vtype = value->type;
1287 *units = value->units;
1288 args[1].length = 0;
1289 if (value->type == Integer) {
1290 if (value->limits.ilims[0] == value->limits.ilims[1]) goto complete;
1291 *limits = value->limits.ilims;
1292 args[1].length = 2*sizeof(int);
1293 } else {
1294 if (value->limits.dlims[0] == value->limits.dlims[1]) goto complete;
1295 *limits = value->limits.dlims;
1296 args[1].length = 2*sizeof(double);
1297 }
1298
1299complete:
1300 if (problem->dbFlag == 1) return CAPS_SUCCESS0;
1301 args[0].members.integer = *vtype;
1302 args[1].members.pointer = (void *) *limits;
1303 args[2].members.string = (char *) *units;
1304 caps_jrnlWrite(CAPS_GETLIMITS83, problem, object, CAPS_SUCCESS0, 3, args,
1305 problem->sNum, problem->sNum);
1306
1307 return CAPS_SUCCESS0;
1308}
1309
1310
1311int
1312caps_setLimits(capsObject *object, enum capsvType vtype, void *limits,
1313 const char *units, int *nErr, capsErrs **errors)
1314{
1315 int *ints, i, status;
1316 double *realp, reals[2];
1317 capsValue *value;
1318 capsObject *pobject;
1319 capsProblem *problem;
1320
1321 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1322 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1323 *nErr = 0;
1324 *errors = NULL((void*)0);
1325 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1326 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1327 if (object->type != VALUE) return CAPS_BADTYPE-306;
1328 if ((object->subtype != USER) && (object->subtype != PARAMETER))
1329 return CAPS_BADTYPE-306;
1330 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1331 value = (capsValue *) object->blind;
1332 status = caps_findProblem(object, CAPS_SETLIMITS84, &pobject);
1333 if (status != CAPS_SUCCESS0) return status;
1334 problem = (capsProblem *) pobject->blind;
1335 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1336
1337 /* ignore if restarting */
1338 if (problem->stFlag == CAPS_JOURNALERR-343) return CAPS_JOURNALERR-343;
1339 if (problem->stFlag == 4) {
1340 status = caps_jrnlEnd(problem);
1341 if (status != CAPS_CLEAN-336) return CAPS_SUCCESS0;
1342 }
1343
1344 if (limits == NULL((void*)0)) {
1345 value->limits.ilims[0] = value->limits.ilims[1] = 0;
1346 value->limits.dlims[0] = value->limits.dlims[1] = 0.0;
1347 return CAPS_SUCCESS0;
1348 }
1349 if (value->type != vtype) {
1350 if (!( ((value->type == Double) || (value->type == DoubleDeriv)) &&
1351 (vtype == Integer) )) return CAPS_BADTYPE-306;
1352 }
1353
1354 status = caps_unitConvertible(units, value->units);
1355 if (status != CAPS_SUCCESS0) return status;
1356
1357 if (value->type == Integer) {
1358 if ( units != NULL((void*)0) ) return CAPS_UNITERR-320;
1359 ints = (int *) limits;
1360 if (ints[0] >= ints[1]) return CAPS_RANGEERR-326;
1361 if (value->length == 1) {
1362 if ((value->vals.integer < ints[0]) ||
1363 (value->vals.integer > ints[1])) return CAPS_RANGEERR-326;
1364 } else {
1365 for (i = 0; i < value->length; i++)
1366 if ((value->vals.integers[i] < ints[0]) ||
1367 (value->vals.integers[i] > ints[1])) return CAPS_RANGEERR-326;
1368 }
1369 value->limits.ilims[0] = ints[0];
1370 value->limits.ilims[1] = ints[1];
1371 } else if ((value->type == Double) || (value->type == DoubleDeriv)) {
1372 if (vtype == Integer) {
1373 ints = (int *) limits;
1374 reals[0] = ints[0];
1375 reals[1] = ints[1];
1376 } else {
1377 realp = (double *) limits;
1378 reals[0] = realp[0];
1379 reals[1] = realp[1];
1380 }
1381 if (reals[0] >= reals[1]) return CAPS_RANGEERR-326;
1382
1383 status = caps_convert(2, units, reals, value->units, reals);
1384 if (status != CAPS_SUCCESS0) return status;
1385
1386 if (value->length == 1) {
1387 if ((value->vals.real < reals[0]) ||
1388 (value->vals.real > reals[1])) return CAPS_RANGEERR-326;
1389 } else {
1390 for (i = 0; i < value->length; i++)
1391 if ((value->vals.reals[i] < reals[0]) ||
1392 (value->vals.reals[i] > reals[1])) return CAPS_RANGEERR-326;
1393 }
1394 value->limits.dlims[0] = reals[0];
1395 value->limits.dlims[1] = reals[1];
1396 } else {
1397 return CAPS_BADTYPE-306;
1398 }
1399
1400 return CAPS_SUCCESS0;
1401}
1402
1403
1404int
1405caps_getValueProps(capsObject *object, int *dim, int *pmtr,
1406 enum capsFixed *lfixed, enum capsFixed *sfixed,
1407 enum capsNull *nval)
1408{
1409 int status, ret;
1410 CAPSLONGunsigned long sNum;
1411 capsValue *value;
1412 capsObject *pobject;
1413 capsProblem *problem;
1414 capsJrnl args[5];
1415
1416 if (dim == NULL((void*)0)) return CAPS_NULLVALUE-307;
1417 if (pmtr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1418 if (lfixed == NULL((void*)0)) return CAPS_NULLVALUE-307;
1419 if (sfixed == NULL((void*)0)) return CAPS_NULLVALUE-307;
1420 if (nval == NULL((void*)0)) return CAPS_NULLVALUE-307;
1421
1422 *dim = *pmtr = 0;
1423 *lfixed = *sfixed = Fixed;
1424 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1425 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1426 if (object->type != VALUE) return CAPS_BADTYPE-306;
1427 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1428 value = (capsValue *) object->blind;
1429 status = caps_findProblem(object, CAPS_GETVALUEPROPS85, &pobject);
1430 if (status != CAPS_SUCCESS0) return status;
1431 problem = (capsProblem *) pobject->blind;
1432
1433 args[0].type = jInteger;
1434 args[1].type = jInteger;
1435 args[2].type = jInteger;
1436 args[3].type = jInteger;
1437 args[4].type = jInteger;
1438 if (problem->dbFlag == 0) {
1439 status = caps_jrnlRead(CAPS_GETVALUEPROPS85, problem, object, 5, args,
1440 &sNum, &ret);
1441 if (status == CAPS_JOURNALERR-343) return status;
1442 if (status == CAPS_JOURNAL-342) {
1443 *dim = args[0].members.integer;
1444 *pmtr = args[1].members.integer;
1445 *lfixed = args[2].members.integer;
1446 *sfixed = args[3].members.integer;
1447 *nval = args[4].members.integer;
1448 return ret;
1449 }
1450 }
1451
1452 args[0].members.integer = *dim = value->dim;
1453 args[1].members.integer = *pmtr = value->gInType;
1454 args[2].members.integer = *lfixed = value->lfixed;
1455 args[3].members.integer = *sfixed = value->sfixed;
1456 args[4].members.integer = *nval = value->nullVal;
1457 if (problem->dbFlag == 1) return CAPS_SUCCESS0;
1458
1459 caps_jrnlWrite(CAPS_GETVALUEPROPS85, problem, object, CAPS_SUCCESS0, 5, args,
1460 problem->sNum, problem->sNum);
1461
1462 return CAPS_SUCCESS0;
1463}
1464
1465
1466int
1467caps_setValueProps(capsObject *object, int dim, enum capsFixed lfixed,
1468 enum capsFixed sfixed, enum capsNull nval,
1469 int *nErr, capsErrs **errors)
1470{
1471 int status;
1472 capsValue *value;
1473 capsObject *pobject;
1474 capsProblem *problem;
1475
1476 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1477 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1478 *nErr = 0;
1479 *errors = NULL((void*)0);
1480 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1481 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1482 if (object->type != VALUE) return CAPS_BADTYPE-306;
1483 if ((object->subtype != PARAMETER) &&
1484 (object->subtype != USER)) return CAPS_BADTYPE-306;
1485 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1486 value = (capsValue *) object->blind;
1487 if ((nval == NotAllowed) &&
1488 (value->nullVal == IsNull)) return CAPS_NULLVALUE-307;
1489 status = caps_findProblem(object, CAPS_SETVALUEPROPS86, &pobject);
1490 if (status != CAPS_SUCCESS0) return status;
1491 problem = (capsProblem *) pobject->blind;
1492 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1493
1494 /* ignore if restarting */
1495 if (problem->stFlag == CAPS_JOURNALERR-343) return CAPS_JOURNALERR-343;
1496 if (problem->stFlag == 4) {
1497 status = caps_jrnlEnd(problem);
1498 if (status != CAPS_CLEAN-336) return CAPS_SUCCESS0;
1499 }
1500
1501 /* check dimension */
1502 if (dim == 0) {
1503 if ((value->ncol != 1) || (value->nrow != 1)) return CAPS_SHAPEERR-322;
1504 } else if (dim == 1) {
1505 if ((value->ncol > 1) && (value->nrow > 1)) return CAPS_SHAPEERR-322;
1506 } else if (dim != 2) {
1507 return CAPS_RANGEERR-326;
1508 }
1509
1510 value->dim = dim;
1511 value->lfixed = lfixed;
1512 value->sfixed = sfixed;
1513 if ((nval == IsNull) && (value->nullVal == NotNull)) return CAPS_SUCCESS0;
1514 if ((nval == NotNull) && (value->nullVal == IsNull)) return CAPS_SUCCESS0;
1515 value->nullVal = nval;
1516
1517 return CAPS_SUCCESS0;
1518}
1519
1520
1521int
1522caps_convertValue(capsObject *object, double inp, const char *units,
1523 double *outp)
1524{
1525 int status, ret;
1526 CAPSLONGunsigned long sNum;
1527 capsObject *pobject;
1528 capsValue *value;
1529 capsProblem *problem;
1530 capsJrnl args[1];
1531
1532 if (object == NULL((void*)0)) return CAPS_NULLOBJ-309;
1533 if (object->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1534 if (object->type != VALUE) return CAPS_BADTYPE-306;
1535 if (object->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1536 value = (capsValue *) object->blind;
1537 if (units == NULL((void*)0)) return CAPS_UNITERR-320;
1538 if (value->units == NULL((void*)0)) return CAPS_UNITERR-320;
1539 status = caps_findProblem(object, CAPS_CONVERTVALUE88, &pobject);
1540 if (status != CAPS_SUCCESS0) return status;
1541 problem = (capsProblem *) pobject->blind;
1542 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1543
1544 args[0].type = jDouble;
1545 status = caps_jrnlRead(CAPS_CONVERTVALUE88, problem, object, 1, args,
1546 &sNum, &ret);
1547 if (status == CAPS_JOURNALERR-343) return status;
1548 if (status == CAPS_JOURNAL-342) {
1549 *outp = args[0].members.real;
1550 return ret;
1551 }
1552
1553 ret = caps_convert(1, units, &inp, value->units, outp);
1554 args[0].members.real = *outp;
1555 caps_jrnlWrite(CAPS_CONVERTVALUE88, problem, object, ret, 1, args,
1556 problem->sNum, problem->sNum);
1557
1558 return ret;
1559}
1560
1561
1562int
1563caps_dupValues(capsValue *val1, capsValue *val2)
1564{
1565 int i, j, len, status;
1566
1567 /* this function assumes that val2 has no allocated data */
1568 val2->type = val1->type;
1569 val2->length = val1->length;
1570 val2->dim = val1->dim;
1571 val2->nrow = val1->nrow;
1572 val2->ncol = val1->ncol;
1573 val2->lfixed = val1->lfixed;
1574 val2->sfixed = val1->sfixed;
1575 val2->nullVal = val1->nullVal;
1576 val2->index = val1->index;
1577 val2->pIndex = val1->pIndex;
1578 val2->gInType = val1->gInType;
1579 val2->partial = NULL((void*)0);
1580 val2->nderiv = 0;
1581 val2->derivs = NULL((void*)0);
1582 if (val1->partial != NULL((void*)0)) {
1583 val2->partial = (int *) EG_alloc(val1->length*sizeof(int));
1584 if (val2->partial == NULL((void*)0)) return EGADS_MALLOC-4;
1585 for (i = 0; i < val1->length; i++) val2->partial[i] = val1->partial[i];
1586 }
1587 if ((val1->nderiv != 0) && (val1->derivs != NULL((void*)0))) {
1588 val2->derivs = (capsDeriv *) EG_alloc(val1->nderiv*sizeof(capsDeriv));
1589 if (val2->derivs == NULL((void*)0)) return EGADS_MALLOC-4;
1590 for (i = 0; i < val1->nderiv; i++) {
1591 val2->derivs[i].name = EG_strdup(val1->derivs[i].name);
1592 val2->derivs[i].len_wrt = val1->derivs[i].len_wrt;
1593 val2->derivs[i].deriv = NULL((void*)0);
1594 }
1595 for (i = 0; i < val1->nderiv; i++) {
1596 if (val2->derivs[i].name == NULL((void*)0)) return EGADS_MALLOC-4;
1597 val2->derivs[i].deriv = (double *) EG_alloc(
1598 val1->length*val1->derivs[i].len_wrt*sizeof(double));
1599 if (val2->derivs[i].deriv == NULL((void*)0)) return EGADS_MALLOC-4;
1600 for (j = 0; j < val1->length*val1->derivs[i].len_wrt; j++)
1601 val2->derivs[i].deriv[j] = val1->derivs[i].deriv[j];
1602 }
1603 val2->nderiv = val1->nderiv;
1604 }
1605
1606 /* set the actual value(s) */
1607 switch (val1->type) {
1608 case Boolean:
1609 if (val1->length == 1) {
1610 val2->vals.integer = val1->vals.integer;
1611 } else {
1612 val2->vals.integers = NULL((void*)0);
1613 if (val1->vals.integers == NULL((void*)0)) break;
1614 val2->vals.integers = (int *) EG_alloc(val1->length*sizeof(int));
1615 if (val2->vals.integers == NULL((void*)0)) return EGADS_MALLOC-4;
1616 for (i = 0; i < val1->length; i++)
1617 val2->vals.integers[i] = val1->vals.integers[i];
1618 }
1619 break;
1620
1621 case Integer:
1622 if (val1->length == 1) {
1623 val2->vals.integer = val1->vals.integer;
1624 } else {
1625 val2->vals.integers = NULL((void*)0);
1626 if (val1->vals.integers != NULL((void*)0)) {
1627 val2->vals.integers = (int *) EG_alloc(val1->length*sizeof(int));
1628 if (val2->vals.integers == NULL((void*)0)) return EGADS_MALLOC-4;
1629 for (i = 0; i < val1->length; i++)
1630 val2->vals.integers[i] = val1->vals.integers[i];
1631 }
1632 }
1633 val2->limits.ilims[0] = val1->limits.ilims[0];
1634 val2->limits.ilims[1] = val1->limits.ilims[1];
1635 break;
1636
1637 case Double:
1638 if (val1->length == 1) {
1639 val2->vals.real = val1->vals.real;
1640 } else {
1641 val2->vals.reals = NULL((void*)0);
1642 if (val1->vals.reals != NULL((void*)0)) {
1643 val2->vals.reals = (double *) EG_alloc(val1->length*sizeof(double));
1644 if (val2->vals.reals == NULL((void*)0)) return EGADS_MALLOC-4;
1645 for (i = 0; i < val1->length; i++)
1646 val2->vals.reals[i] = val1->vals.reals[i];
1647 }
1648 }
1649 val2->limits.dlims[0] = val1->limits.dlims[0];
1650 val2->limits.dlims[1] = val1->limits.dlims[1];
1651 break;
1652
1653 case String:
1654 val2->vals.string = NULL((void*)0);
1655 if ((val1->vals.string != NULL((void*)0)) && (strlen(val1->vals.string) > 0)) {
1656 j = strlen(val1->vals.string) + 1;
1657 val2->vals.string = (char *) EG_alloc(j*sizeof(char));
1658 if (val2->vals.string == NULL((void*)0)) return EGADS_MALLOC-4;
1659 for (i = 0; i < j; i++)
1660 val2->vals.string[i] = val1->vals.string[i];
1661 }
1662 break;
1663
1664 case Tuple:
1665 val2->vals.tuple = NULL((void*)0);
1666 if (val1->vals.tuple == NULL((void*)0))
1667 break;
1668 status = caps_makeTuple(val1->length, &val2->vals.tuple);
1669 if (status != CAPS_SUCCESS0) return status;
1670 if (val2->vals.tuple == NULL((void*)0)) return EGADS_MALLOC-4; /* for splint */
1671 for (i = 0; i < val1->length; i++) {
1672 val2->vals.tuple[i].name = EG_strdup(val1->vals.tuple[i].name);
1673 val2->vals.tuple[i].value = EG_strdup(val1->vals.tuple[i].value);
1674 if ((val1->vals.tuple[i].name != NULL((void*)0)) &&
1675 (val2->vals.tuple[i].name == NULL((void*)0))) return EGADS_MALLOC-4;
1676 if ((val1->vals.tuple[i].value != NULL((void*)0)) &&
1677 (val2->vals.tuple[i].value == NULL((void*)0))) return EGADS_MALLOC-4;
1678 }
1679 break;
1680
1681 case Pointer:
1682 case PointerMesh:
1683 val2->vals.AIMptr = val1->vals.AIMptr;
1684
1685 }
1686
1687 /* copy units */
1688 val2->units = NULL((void*)0);
1689 if (val1->units != NULL((void*)0)) {
1690 len = strlen(val1->units) + 1;
1691 val2->units = (char *) EG_alloc(len*sizeof(char));
1692 if (val2->units == NULL((void*)0)) return EGADS_MALLOC-4;
1693 for (i = 0; i < len; i++) val2->units[i] = val1->units[i];
1694 }
1695
1696 /* copy mesh writer */
1697 val2->meshWriter = NULL((void*)0);
1698 if (val1->meshWriter != NULL((void*)0)) {
1699 len = strlen(val1->meshWriter) + 1;
1700 val2->meshWriter = (char *) EG_alloc(len*sizeof(char));
1701 if (val2->meshWriter == NULL((void*)0)) return EGADS_MALLOC-4;
1702 for (i = 0; i < len; i++) val2->meshWriter[i] = val1->meshWriter[i];
1703 }
1704
1705 /* linkage */
1706 val2->link = val1->link;
1707 val2->linkMethod = val1->linkMethod;
1708
1709 return CAPS_SUCCESS0;
1710}
1711
1712
1713static int
1714caps_compatValues(capsValue *val1, capsValue *val2, capsProblem *problem)
1715{
1716 int status;
1717 ut_unit *utunit1, *utunit2;
1718
1719 /* check units */
1720 if ((val1->units != NULL((void*)0)) && (val2->units == NULL((void*)0))) return CAPS_UNITERR-320;
1721 if ((val1->units == NULL((void*)0)) && (val2->units != NULL((void*)0))) return CAPS_UNITERR-320;
1722 if ((val1->units != NULL((void*)0)) && (val2->units != NULL((void*)0))) {
1723 if (strcmp(val1->units, val2->units) != 0) {
1724 utunit1 = ut_parse((ut_system *) problem->utsystem, val1->units, UT_ASCII);
1725 utunit2 = ut_parse((ut_system *) problem->utsystem, val2->units, UT_ASCII);
1726 status = ut_are_convertible(utunit1, utunit2);
1727 ut_free(utunit1);
1728 ut_free(utunit2);
1729 if (status == 0) return CAPS_UNITERR-320;
1730 }
1731 }
1732
1733 /* check type */
1734 if (val1->type != val2->type) return CAPS_BADTYPE-306;
1735
1736 /* check shape */
1737 if (val2->lfixed == Fixed)
1738 if (val1->length != val2->length) return CAPS_SHAPEERR-322;
1739 if (val2->sfixed == Fixed) {
1740 if (val2->dim > val1->dim) return CAPS_SHAPEERR-322;
1741 if (val2->nrow != val1->nrow) return CAPS_SHAPEERR-322;
1742 if (val2->ncol != val1->ncol) return CAPS_SHAPEERR-322;
1743 } else {
1744 if (val2->dim == Scalar) {
1745 if (val1->length != 1) return CAPS_SHAPEERR-322;
1746 } else if (val2->dim == Vector) {
1747 if ((val1->ncol != 1) && (val1->nrow != 1)) return CAPS_SHAPEERR-322;
1748 }
1749 }
1750
1751 return CAPS_SUCCESS0;
1752}
1753
1754
1755int
1756caps_transferValueX(capsObject *source, enum capstMethod method,
1757 capsObject *target, int *nErr, capsErrs **errors)
1758{
1759 int status, vlen, rank, ncol, nrow;
1760 char *iunits;
1761 double *ireals;
1762 const void *data;
1763 const int *partial;
1764 const char *units;
1765 const double *reals;
1766 capsValue *value, *sval;
1767 capsProblem *problem;
1768 capsObject *pobject, *last;
1769 enum capsvType vtype;
1770
1771 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1772 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1773 *nErr = 0;
1774 *errors = NULL((void*)0);
1775 if (source == NULL((void*)0)) return CAPS_NULLOBJ-309;
1776 if (source->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1777 if ((source->type != VALUE) &&
1778 (source->type != DATASET)) return CAPS_BADTYPE-306;
1779 if (source->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1780 if (target == NULL((void*)0)) return CAPS_NULLOBJ-309;
1781 if (target->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1782 if (target->type != VALUE) return CAPS_BADTYPE-306;
1783 if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE-306;
1784 if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE-306;
1785 if (target->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1786 value = (capsValue *) target->blind;
1787 status = caps_findProblem(target, 9999, &pobject);
1788 if (status != CAPS_SUCCESS0) return status;
1789 problem = (capsProblem *) pobject->blind;
1790
1791 if (source->type == VALUE) {
1792
1793 status = caps_getValuX(source, &vtype, &nrow, &ncol, &data, &partial,
1794 &units, nErr, errors);
1795 if (status != CAPS_SUCCESS0) return status;
1796 last = value->link;
1797 value->link = NULL((void*)0);
1798 status = caps_setValuX(target, vtype, nrow, ncol, data, partial, units,
1799 nErr, errors);
1800 value->link = last;
1801 if (status != CAPS_SUCCESS0) return status;
1802
1803 } else {
1804
1805 if (method == Copy) {
1806
1807 sval = (capsValue *) source->blind;
1808 if (sval->nullVal == IsNull) return CAPS_NULLVALUE-307;
1809 status = caps_getDataX(source, &vlen, &rank, &reals, &units);
1810 if (status != CAPS_SUCCESS0) return status;
1811 /* check for compatibility */
1812 status = caps_makeVal(Double, vlen*rank, reals, &sval);
1813 if (status != CAPS_SUCCESS0) return status;
1814 sval->units = (char *) units;
1815 sval->ncol = vlen;
1816 sval->nrow = rank;
1817 if (rank != 1) sval->dim = Array2D;
1818 status = caps_compatValues(sval, value, problem);
1819 if (status != CAPS_SUCCESS0) {
1820 if (sval->length > 1) EG_free(sval->vals.reals);
1821 EG_free(sval);
1822 return status;
1823 }
1824 value->ncol = vlen;
1825 value->nrow = rank;
1826 if (rank != 1) value->dim = Array2D;
1827 last = value->link;
1828 value->link = NULL((void*)0);
1829 status = caps_setValuX(target, Double, rank, vlen, reals, NULL((void*)0), units,
1830 nErr, errors);
1831 value->link = last;
1832 if (sval->length > 1) EG_free(sval->vals.reals);
1833 EG_free(sval);
1834 if (status != CAPS_SUCCESS0) return status;
1835
1836 } else {
1837
1838 if (source->subtype == UNCONNECTED) return CAPS_BADMETHOD-318;
1839
1840 /* Integrate / weighted average */
1841 status = caps_integrateData(source, method, &rank, &ireals, &iunits);
1842 if (status != CAPS_SUCCESS0) return status;
1843 status = caps_makeVal(Double, rank, ireals, &sval);
1844 if (status != CAPS_SUCCESS0) {
1845 EG_free(ireals);
1846 EG_free(iunits);
1847 return status;
1848 }
1849 sval->units = iunits;
1850 sval->nrow = rank;
1851 sval->ncol = 1;
1852 status = caps_compatValues(sval, value, problem);
1853 EG_free(sval->units);
1854 if (sval->length > 1) EG_free(sval->vals.reals);
1855 EG_free(sval);
1856 if (status != CAPS_SUCCESS0) {
1857 EG_free(ireals);
1858 return status;
1859 }
1860 last = value->link;
1861 value->link = NULL((void*)0);
1862 status = caps_setValuX(target, Double, rank, 1, ireals, NULL((void*)0), iunits,
1863 nErr, errors);
1864 value->link = last;
1865 EG_free(ireals);
1866 if (status != CAPS_SUCCESS0) return status;
1867 }
1868
1869 }
1870
1871 /* mark owner */
1872 caps_freeOwner(&target->last);
1873 problem->sNum += 1;
1874 target->last.sNum = problem->sNum;
1875 status = caps_addHistory(target, problem);
1876 if (status != CAPS_SUCCESS0)
1877 printf(" CAPS Warning: caps_addHistory = %d (caps_transferValues)\n",
1878 status);
1879
1880 status = caps_writeValueObj(problem, target);
1881 if (status != CAPS_SUCCESS0)
1882 printf(" CAPS Warning: caps_writeValueObj = %d (caps_transferValues)\n",
1883 status);
1884
1885 /* invalidate any link if exists */
1886 value->linkMethod = Copy;
1887 value->link = NULL((void*)0);
1888
1889 return CAPS_SUCCESS0;
1890}
1891
1892
1893int
1894caps_transferValues(capsObject *source, enum capstMethod method,
1895 capsObject *target, int *nErr, capsErrs **errors)
1896{
1897 int stat, ret;
1898 CAPSLONGunsigned long sNum;
1899 capsObject *pobject;
1900 capsProblem *problem;
1901 capsJrnl args[2];
1902
1903 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1904 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1905 *nErr = 0;
1906 *errors = NULL((void*)0);
1907 if (source == NULL((void*)0)) return CAPS_NULLOBJ-309;
1908 if (source->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1909 if ((source->type != VALUE) &&
1910 (source->type != DATASET)) return CAPS_BADTYPE-306;
1911 if (source->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1912 if (target == NULL((void*)0)) return CAPS_NULLOBJ-309;
1913 if (target->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1914 if (target->type != VALUE) return CAPS_BADTYPE-306;
1915 if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE-306;
1916 if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE-306;
1917 if (target->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1918 stat = caps_findProblem(target, CAPS_TRANSFERVALUES89, &pobject);
1919 if (stat != CAPS_SUCCESS0) return stat;
1920 problem = (capsProblem *) pobject->blind;
1921 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1922
1923 args[0].type = jInteger;
1924 args[1].type = jErr;
1925 stat = caps_jrnlRead(CAPS_TRANSFERVALUES89, problem, target, 2, args,
1926 &sNum, &ret);
1927 if (stat == CAPS_JOURNALERR-343) return stat;
1928 if (stat == CAPS_JOURNAL-342) {
1929 *nErr = args[0].members.integer;
1930 *errors = args[1].members.errs;
1931 return ret;
1932 }
1933
1934 if (ret == CAPS_SUCCESS0) {
1935 ret = caps_transferValueX(source, method, target, nErr, errors);
1936 *nErr = 0;
1937 if (*errors != NULL((void*)0)) *nErr = (*errors)->nError;
1938 }
1939 args[0].members.integer = *nErr;
1940 args[1].members.errs = *errors;
1941 caps_jrnlWrite(CAPS_TRANSFERVALUES89, problem, target, ret, 2, args, sNum,
1942 problem->sNum);
1943
1944 return ret;
1945}
1946
1947
1948int
1949caps_linkValue(/*@null@*/ capsObject *link, enum capstMethod method,
1950 capsObject *target, int *nErr, capsErrs **errors)
1951{
1952 int status, rank, vlen;
1953 const double *reals;
1954 const char *units;
1955 capsValue *value, *sval;
1956 capsObject *source, *pobject;
1957 capsProblem *problem;
1958
1959 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
1960 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
1961 *nErr = 0;
1962 *errors = NULL((void*)0);
1963 if (target == NULL((void*)0)) return CAPS_NULLOBJ-309;
1964 if (target->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
1965 if (target->type != VALUE) return CAPS_BADTYPE-306;
1966 if (target->subtype == GEOMETRYOUT) return CAPS_BADTYPE-306;
1967 if (target->subtype == ANALYSISOUT) return CAPS_BADTYPE-306;
1968 if (target->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
1969 value = (capsValue *) target->blind;
1970 status = caps_findProblem(target, CAPS_LINKVALUE90, &pobject);
1971 if (status != CAPS_SUCCESS0) return status;
1972 problem = (capsProblem *) pobject->blind;
1973 if (problem->dbFlag == 1) return CAPS_READONLYERR-315;
1974
1975 if (target->type == VALUE) {
1976 if (target->subtype == GEOMETRYIN) {
1977 if (pobject->subtype == STATIC) return CAPS_READONLYERR-315;
1978 if (method != Copy) return CAPS_BADMETHOD-318;
1979 }
1980 }
1981
1982 /* ignore if restarting */
1983 if (problem->stFlag == CAPS_JOURNALERR-343) return CAPS_JOURNALERR-343;
1984 if (problem->stFlag == 4) {
1985 status = caps_jrnlEnd(problem);
1986 if (status != CAPS_CLEAN-336) return CAPS_SUCCESS0;
1987 }
1988
1989 if (link == NULL((void*)0)) {
1990 /* mark owner */
1991 caps_freeOwner(&target->last);
1992 problem->sNum += 1;
1993 target->last.sNum = problem->sNum;
1994 status = caps_addHistory(target, problem);
1995 if (status != CAPS_SUCCESS0)
1996 printf(" CAPS Warning: caps_addHistory = %d (caps_linkValue)\n", status);
1997 /* remove existing link */
1998 value->linkMethod = Copy;
1999 value->link = NULL((void*)0);
2000 status = caps_writeSerialNum(problem);
2001 if (status != CAPS_SUCCESS0)
2002 printf(" CAPS Warning: caps_writePSerialNum = %d (caps_linkValue)\n",
2003 status);
2004 if (target->type == VALUE) {
2005 status = caps_writeValueObj(problem, target);
2006 if (status != CAPS_SUCCESS0)
2007 printf(" CAPS Warning: caps_writeValueObj = %d (caps_linkValue)\n",
2008 status);
2009 }
2010 return CAPS_SUCCESS0;
2011 }
2012
2013 /* look at link */
2014 if (link->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
2015 if (link->type == VALUE) {
2016
2017 if (target->subtype == USER) return CAPS_BADTYPE-306;
2018 if (method != Copy) return CAPS_BADMETHOD-318;
2019 source = link;
2020 do {
2021 if (source->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
2022 if (source->type != VALUE) return CAPS_BADTYPE-306;
2023 if (source->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
2024 sval = (capsValue *) source->blind;
2025 if (sval->link == target) return CAPS_CIRCULARLINK-319;
2026 source = sval->link;
2027 } while (sval->link != NULL((void*)0));
2028
2029 if ((sval->type == Pointer) || (sval->type == PointerMesh)) {
2030 /* must have the same "units" */
2031 if ((sval->units != NULL((void*)0)) || (value->units != NULL((void*)0))) {
2032 if (sval->units == NULL((void*)0)) return CAPS_UNITERR-320;
2033 if (value->units == NULL((void*)0)) return CAPS_UNITERR-320;
2034 if (strcmp(value->units, sval->units) != 0) return CAPS_UNITERR-320;
2035 }
2036 } else {
2037 /* make sure we are compatible */
2038 status = caps_compatValues(sval, value, problem);
2039 if (status != CAPS_SUCCESS0) return status;
2040 }
2041
2042 } else if (link->type == DATASET) {
2043
2044 status = caps_getDataX(link, &vlen, &rank, &reals, &units);
2045 if (status != CAPS_SUCCESS0) return status;
2046
2047 /* check for compatibility */
2048 status = caps_makeVal(Double, vlen*rank, reals, &sval);
2049 if (status != CAPS_SUCCESS0) return status;
2050 sval->units = (char *) units;
2051 if (rank != 1) {
2052 sval->dim = Array2D;
2053 sval->nrow = rank;
2054 sval->ncol = vlen;
2055 }
2056 status = caps_compatValues(sval, value, problem);
2057 if (sval->length > 1) EG_free(sval->vals.reals);
2058 EG_free(sval);
2059 if (status != CAPS_SUCCESS0) return status;
2060
2061 } else {
2062 return CAPS_BADTYPE-306;
2063 }
2064
2065 /* set the link */
2066 value->linkMethod = method;
2067 value->link = link;
2068
2069 /* check for circular auto execution links */
2070 if (target->subtype == ANALYSISIN) {
2071 status = caps_circularAutoExecs(target, NULL((void*)0));
2072 if (status != CAPS_SUCCESS0) {
2073 value->linkMethod = Copy;
2074 value->link = NULL((void*)0);
2075 return CAPS_CIRCULARLINK-319;
2076 }
2077 }
2078
2079 caps_freeOwner(&target->last);
2080 problem->sNum += 1;
2081 target->last.sNum = problem->sNum;
2082 status = caps_addHistory(target, problem);
2083 if (status != CAPS_SUCCESS0)
2084 printf(" CAPS Warning: caps_addHistory = %d (caps_linkValue)\n", status);
2085 status = caps_writeSerialNum(problem);
2086 if (status != CAPS_SUCCESS0)
2087 printf(" CAPS Warning: caps_writeSerialNum = %d (caps_linkValue)!\n",
2088 status);
2089 status = caps_writeValueObj(problem, target);
2090 if (status != CAPS_SUCCESS0)
2091 printf(" CAPS Warning: caps_writeValueObj = %d (caps_linkValue)!\n",
2092 status);
2093
2094 return status;
2095}
2096
2097
2098int
2099caps_hasDeriv(capsObject *vobj, int *nderiv, char ***names,
2100 int *nErr, capsErrs **errors)
2101{
2102 int i, status, ret;
2103 char **namex, **namey;
2104 CAPSLONGunsigned long sNum;
2105 capsValue *value;
2106 capsObject *pobject, *source, *last;
2107 capsProblem *problem;
2108 capsJrnl args[1];
2109
2110 *nErr = 0;
2111 *errors = NULL((void*)0);
2112 *nderiv = 0;
2113 *names = NULL((void*)0);
2114 if (vobj == NULL((void*)0)) return CAPS_NULLOBJ-309;
2115 if (vobj->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
2116 if (vobj->type != VALUE) return CAPS_BADTYPE-306;
2117 if (vobj->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
2118 status = caps_findProblem(vobj, CAPS_HASDERIV91, &pobject);
2119 if (status != CAPS_SUCCESS0) return status;
2120 problem = (capsProblem *) pobject->blind;
2121
2122 args[0].type = jStrings;
2123 if (problem->dbFlag == 0) {
2124 status = caps_jrnlRead(CAPS_HASDERIV91, problem, vobj, 1, args, &sNum,
2125 &ret);
2126 if (status == CAPS_JOURNALERR-343) return status;
2127 if (status == CAPS_JOURNAL-342) {
2128 if (ret == CAPS_SUCCESS0) {
2129 *nderiv = args[0].num;
2130 namey = args[0].members.strings;
2131 namex = (char **) EG_alloc(args[0].num*sizeof(char *));
2132 if (namex == NULL((void*)0)) {
2133 ret = EGADS_MALLOC-4;
2134 } else {
2135 for (i = 0; i < args[0].num; i++) namex[i] = namey[i];
2136 }
2137 *names = namex;
2138 }
2139 return ret;
2140 }
2141 }
2142
2143 args[0].num = 0;
2144 args[0].members.strings = NULL((void*)0);
2145 source = vobj;
2146 do {
2147 if (source->magicnumber != CAPSMAGIC1234321) {
2148 status = CAPS_BADOBJECT-310;
2149 goto herr;
2150 }
2151 if (source->type != VALUE) {
2152 status = CAPS_BADTYPE-306;
2153 goto herr;
2154 }
2155 if (source->blind == NULL((void*)0)) {
2156 status = CAPS_NULLBLIND-321;
2157 goto herr;
2158 }
2159 value = (capsValue *) source->blind;
2160 if (value->link == vobj) {
2161 status = CAPS_CIRCULARLINK-319;
2162 goto herr;
2163 }
2164 last = source;
2165 source = value->link;
2166 } while (value->link != NULL((void*)0));
2167
2168 /* do we need to update our value? */
2169 if (problem->dbFlag == 0)
2170 if (last->subtype == ANALYSISOUT) {
2171 status = caps_updateAnalysisOut(last, CAPS_HASDERIV91, nErr, errors);
2172 if (status != CAPS_SUCCESS0) goto herr;
2173 } else if (vobj->subtype == GEOMETRYOUT) {
2174 /* make sure geometry is up-to-date */
2175 status = caps_build(pobject, nErr, errors);
2176 if ((status != CAPS_SUCCESS0) && (status != CAPS_CLEAN-336)) goto herr;
2177 }
2178
2179 /* check the value object after it has been updated */
2180 value = (capsValue *) vobj->blind;
2181 if (value->type != DoubleDeriv) {
2182 status = CAPS_BADTYPE-306;
2183 goto herr;
2184 }
2185 if (value->nderiv == 0) {
2186 status = CAPS_SUCCESS0;
2187 goto herr;
2188 }
2189
2190 status = EGADS_MALLOC-4;
2191 namex = (char **) EG_alloc(value->nderiv*sizeof(char *));
2192 if (namex != NULL((void*)0)) {
2193 status = CAPS_SUCCESS0;
2194 for (i = 0; i < value->nderiv; i++) namex[i] = value->derivs[i].name;
2195 args[0].num = *nderiv = value->nderiv;
2196 args[0].members.strings = *names = namex;
2197 }
2198
2199herr:
2200 if (problem->dbFlag == 0)
2201 caps_jrnlWrite(CAPS_HASDERIV91, problem, vobj, status, 1, args, problem->sNum,
2202 problem->sNum);
2203
2204 return status;
2205}
2206
2207
2208static int
2209caps_registerGIN(capsProblem *problem, const char *fullname)
2210{
2211 int i, j, i1, i2, len, len_wrt, index, irow, icol;
2212 char name[MAX_NAME_LEN64];
2213 capsValue *value, *vout;
2214 capsRegGIN *regGIN;
2215 capsDeriv *derivs;
2216
2217 len = strlen(fullname);
2218 irow = icol = 0;
2219 for (i = 0; i < len; i++) {
2220 name[i] = fullname[i];
2221 if (fullname[i] == '[') break;
2222 }
2223 name[i] = '\0';
2224 i1 = i2 = 0;
2225 if (i != len) {
2226 for (j = i+1; j < len; j++)
2227 if (fullname[j] == ',') break;
2228 if (j == len) {
2229 sscanf(&fullname[i+1], "%d", &i1);
2230 } else {
2231 sscanf(&fullname[i+1], "%d,%d", &i1, &i2);
2232 }
2233 }
2234
2235 for (index = 1; index <= problem->nGeomIn; index++)
2236 if (strcmp(problem->geomIn[index-1]->name,name) == 0) break;
2237 if (index > problem->nGeomIn) {
2238 printf(" CAPS Error: Object Not Found: %s (caps_getDeriv)!\n", name);
2239 return CAPS_NOTFOUND-303;
2240 }
2241 value = (capsValue *) problem->geomIn[index-1]->blind;
2242 if (value == NULL((void*)0)) {
2243 printf(" CAPS Error: Object: %s has NULL pointer (caps_getDeriv)!\n", name);
2244 return CAPS_NULLOBJ-309;
2245 }
2246
2247 if (i1 > 0) {
2248 if ((value->nrow == 1) && (value->ncol == 1)) {
2249 printf(" CAPS Error: Object: %s has no index (caps_getDeriv)!\n", name);
2250 return CAPS_BADINDEX-304;
2251 }
2252 if (((i1 > 0) && (i2 <= 0)) ||
2253 ((i1 <= 0) && (i2 > 0))) {
2254 printf(" CAPS Error: Object: both indices in %s must be positive (caps_getDeriv)!\n",
2255 fullname);
2256 return CAPS_BADINDEX-304;
2257 }
2258 if (i2 != 0) {
2259 irow = i1;
2260 icol = i2;
2261 } else {
2262 if (value->nrow == 1) {
2263 irow = 1;
2264 icol = i1;
2265 } else {
2266 irow = i1;
2267 icol = 1;
2268 }
2269 }
2270 if ((irow < 1) || (irow > value->nrow)) {
2271 printf(" CAPS Error: Object: %s irow = %d [1-%d] (caps_getDeriv)!\n",
2272 name, irow, value->nrow);
2273 return CAPS_BADINDEX-304;
2274 }
2275 if ((icol < 1) || (icol > value->ncol)) {
2276 printf(" CAPS Error: Object: %s icol = %d [1-%d] (caps_getDeriv)!\n",
2277 name, icol, value->ncol);
2278 return CAPS_BADINDEX-304;
2279 }
2280 }
2281
2282 /* are we already in the list? */
2283 for (i = 0; i < problem->nRegGIN; i++)
2284 if ((problem->regGIN[i].index == index) &&
2285 (problem->regGIN[i].irow == irow) &&
2286 (problem->regGIN[i].icol == icol)) return CAPS_SUCCESS0;
2287
2288 /* make room */
2289 len = problem->nRegGIN + 1;
2290 regGIN = (capsRegGIN *) EG_reall(problem->regGIN, len*sizeof(capsRegGIN));
2291 if (regGIN == NULL((void*)0)) {
2292 printf(" CAPS Error: Cant ReAlloc registry for %s (caps_getDeriv)!\n",
2293 fullname);
2294 return EGADS_MALLOC-4;
2295 }
2296 problem->regGIN = regGIN;
2297
2298 len_wrt = 1;
2299 if (irow == 0 && icol == 0) len_wrt = value->length;
2300
2301 for (i = 0; i < problem->nGeomOut; i++) {
2302 if (problem->geomOut[i] == NULL((void*)0)) continue;
2303 if (problem->geomOut[i]->magicnumber != CAPSMAGIC1234321) continue;
2304 if (problem->geomOut[i]->blind == NULL((void*)0)) continue;
2305 vout = (capsValue *) problem->geomOut[i]->blind;
2306
2307 derivs = (capsDeriv *) EG_reall(vout->derivs, len*sizeof(capsDeriv));
2308 if (derivs == NULL((void*)0)) {
2309 printf(" CAPS Error: Cant Malloc dots for %s (caps_getDeriv)!\n",
2310 problem->geomOut[i]->name);
2311 return EGADS_MALLOC-4;
2312 }
2313 vout->derivs = derivs;
2314
2315 vout->derivs[len-1].name = NULL((void*)0);
2316 vout->derivs[len-1].len_wrt = len_wrt;
2317 vout->derivs[len-1].deriv = NULL((void*)0);
2318 vout->nderiv = len;
2319 }
2320 for (i = 0; i < problem->nGeomOut; i++) {
2321 if (problem->geomOut[i] == NULL((void*)0)) continue;
2322 if (problem->geomOut[i]->magicnumber != CAPSMAGIC1234321) continue;
2323 if (problem->geomOut[i]->blind == NULL((void*)0)) continue;
2324 vout = (capsValue *) problem->geomOut[i]->blind;
2325 vout->derivs[len-1].name = EG_strdup(fullname);
2326 }
2327
2328 problem->regGIN[len-1].name = EG_strdup(fullname);
2329 problem->regGIN[len-1].index = index;
2330 problem->regGIN[len-1].irow = irow;
2331 problem->regGIN[len-1].icol = icol;
2332 problem->nRegGIN = len;
2333
2334 return CAPS_SUCCESS0;
2335}
2336
2337
2338int
2339caps_getDeriv(capsObject *vobj, const char *name, int *len, int *len_wrt,
2340 double **deriv, int *nErr, capsErrs **errors)
2341{
2342 int i, ret, ipmtr, irow, icol, status, nbody, buildTo, builtTo;
2343 int irs, ire, ics, ice, index, outLevel;
2344 CAPSLONGunsigned long sNum;
2345 capsValue *valueOut, *value_wrt;
2346 capsProblem *problem;
2347 capsObject *pobject;
2348 capsJrnl args[5];
2349 size_t length;
2350 modl_T *MODL;
2351
2352 if (nErr == NULL((void*)0)) return CAPS_NULLVALUE-307;
2353 if (errors == NULL((void*)0)) return CAPS_NULLVALUE-307;
2354 if (len == NULL((void*)0)) return CAPS_NULLVALUE-307;
2355 if (len_wrt == NULL((void*)0)) return CAPS_NULLVALUE-307;
2356 if (deriv == NULL((void*)0)) return CAPS_NULLVALUE-307;
2357 *nErr = 0;
2358 *errors = NULL((void*)0);
2359 *len = *len_wrt = 0;
2360 *deriv = NULL((void*)0);
2361 if (vobj == NULL((void*)0)) return CAPS_NULLOBJ-309;
2362 if (vobj->magicnumber != CAPSMAGIC1234321) return CAPS_BADOBJECT-310;
2363 if (vobj->type != VALUE) return CAPS_BADTYPE-306;
2364 if (vobj->blind == NULL((void*)0)) return CAPS_NULLBLIND-321;
2365 if (name == NULL((void*)0)) return CAPS_NULLNAME-308;
2366 status = caps_findProblem(vobj, CAPS_GETDERIV92, &pobject);
2367 if (status != CAPS_SUCCESS0) return status;
2368 problem = (capsProblem *) pobject->blind;
2369
2370 args[0].type = jInteger;
2371 args[1].type = jInteger;
2372 args[2].type = jPointer;
2373 args[3].type = jInteger;
2374 args[4].type = jErr;
2375 if (problem->dbFlag == 0) {
2376 status = caps_jrnlRead(CAPS_GETDERIV92, problem, vobj, 5, args, &sNum,
2377 &ret);
2378 if (status == CAPS_JOURNALERR-343) return status;
2379 if (status == CAPS_JOURNAL-342) {
2380 *len = args[0].members.integer;
2381 *len_wrt = args[1].members.integer;
2382 *deriv = (double *) args[2].members.pointer;
2383 *nErr = args[3].members.integer;
2384 *errors = args[4].members.errs;
2385 return ret;
2386 }
2387 }
2388
2389 sNum = problem->sNum;
2390
2391 /* do we need to update our value? */
2392 if (problem->dbFlag == 0)
2393 if (vobj->subtype == ANALYSISOUT) {
2394 status = caps_updateAnalysisOut(vobj, CAPS_GETDERIV92, nErr, errors);
2395 if (status != CAPS_SUCCESS0) return status;
2396 } else if (vobj->subtype == GEOMETRYOUT) {
2397 /* make sure geometry is up-to-date */
2398 status = caps_build(pobject, nErr, errors);
2399 if ((status != CAPS_SUCCESS0) && (status != CAPS_CLEAN-336)) goto finis;
2400
2401 status = caps_registerGIN(problem, name);
2402 if (status != CAPS_SUCCESS0) goto finis;
2403 }
2404
2405 /* check the type after updating */
2406 valueOut = (capsValue *) vobj->blind;
2407 if (valueOut->type != DoubleDeriv) {
2408 status = CAPS_BADTYPE-306;
2409 goto finis;
2410 }
2411
2412 for (i = 0; i < valueOut->nderiv; i++) {
2413 if (strcmp(name, valueOut->derivs[i].name) != 0) continue;
2414 if ((valueOut->derivs[i].deriv == NULL((void*)0)) && (vobj->subtype == GEOMETRYOUT)) {
2415 index = problem->regGIN[i].index;
2416 irow = problem->regGIN[i].irow;
2417 icol = problem->regGIN[i].icol;
2418
2419 if (problem->geomIn[index-1] == NULL((void*)0)) return CAPS_NULLOBJ-309;
2420 value_wrt = (capsValue *) problem->geomIn[index-1]->blind;
2421 ipmtr = value_wrt->pIndex;
2422
2423 if (irow == 0 && icol == 0) {
2424 irs = ics = 1;
2425 ire = value_wrt->nrow; ice = value_wrt->ncol;
2426 } else {
2427 irs = irow; ics = icol;
2428 ire = irow; ice = icol;
2429 }
2430
2431 for (irow = irs; irow <= ire; irow++) {
2432 for (icol = ics; icol <= ice; icol++) {
2433 /* clear all then set */
2434 status = ocsmSetDtime(problem->modl, 0);
2435 if (status != SUCCESS0) goto finis;
2436 status = ocsmSetVelD(problem->modl, 0, 0, 0, 0.0);
2437 if (status != SUCCESS0) goto finis;
2438 status = ocsmSetVelD(problem->modl, ipmtr, irow, icol, 1.0);
2439 if (status != SUCCESS0) goto finis;
2440 buildTo = 0;
2441 nbody = 0;
2442 outLevel = ocsmSetOutLevel(0);
2443 if (problem->outLevel > 0)
2444 printf(" CAPS Info: Building sensitivity information for: %s[%d,%d]\n",
2445 problem->geomIn[index-1]->name, irow, icol);
2446 status = ocsmBuild(problem->modl, buildTo, &builtTo, &nbody, NULL((void*)0));
2447 ocsmSetOutLevel(outLevel);
2448 /* printf(" CAPS Info: parameter %d %d %d sensitivity status = %d\n",
2449 open, irow, icol, status); */
2450 fflush(stdoutstdout);
2451 if (status != SUCCESS0) goto finis;
2452 caps_geomOutSensit(problem, ipmtr, irow, icol);
2453 MODL = (modl_T*)problem->modl;
2454 if (MODL->dtime != 0 && problem->outLevel > 0)
2455 printf(" CAPS Info: Sensitivity finite difference used for: %s[%d,%d]\n",
2456 problem->geomIn[index-1]->name, irow, icol);
2457 }
2458 }
2459 }
2460 *len = valueOut->length;
2461 *len_wrt = valueOut->derivs[i].len_wrt;
2462 *deriv = valueOut->derivs[i].deriv;
2463 status = CAPS_SUCCESS0;
2464 goto finis;
2465 }
2466 status = CAPS_NOTFOUND-303;
2467
2468finis:
2469 if (problem->dbFlag == 1) return status;
2470 length = *len;
2471 length *= *len_wrt*sizeof(double);
2472 args[0].members.integer = *len;
2473 args[1].members.integer = *len_wrt;
2474 args[2].members.pointer = *deriv;
2475 args[2].length = length;
2476 args[3].members.integer = *nErr;
2477 args[4].members.errs = *errors;
2478 caps_jrnlWrite(CAPS_GETDERIV92, problem, vobj, status, 5, args, sNum,
2479 problem->sNum);
2480
2481 return status;
2482}