VIS
|
00001 00037 #include "ioInt.h" 00038 00039 static char rcsid[] UNUSED = "$Id: ioTable.c,v 1.8 2002/09/08 23:40:00 fabio Exp $"; 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Constant declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 00046 /*---------------------------------------------------------------------------*/ 00047 /* Type declarations */ 00048 /*---------------------------------------------------------------------------*/ 00049 00050 00051 /*---------------------------------------------------------------------------*/ 00052 /* Stucture declarations */ 00053 /*---------------------------------------------------------------------------*/ 00054 00055 00056 /*---------------------------------------------------------------------------*/ 00057 /* Variable declarations */ 00058 /*---------------------------------------------------------------------------*/ 00059 00060 00061 /*---------------------------------------------------------------------------*/ 00062 /* Macro declarations */ 00063 /*---------------------------------------------------------------------------*/ 00064 00065 00068 /*---------------------------------------------------------------------------*/ 00069 /* Static function prototypes */ 00070 /*---------------------------------------------------------------------------*/ 00071 00072 static void _IoSymValueFree(IoSymValue_t *value); 00073 static int _IoSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numIp, int numOp); 00074 static int _IoDefaultSymCubeInsertInTable(Tbl_Table_t *table, array_t *symCube, int numOp); 00075 static Tbl_Entry_t * _IoSymValueTransformToEntry(IoSymValue_t *value, Var_Variable_t *var, Tbl_Table_t *table); 00076 static int VariableReadIndex(Var_Variable_t *var, char *value); 00077 00081 /*---------------------------------------------------------------------------*/ 00082 /* Definition of exported functions */ 00083 /*---------------------------------------------------------------------------*/ 00084 00085 /*---------------------------------------------------------------------------*/ 00086 /* Definition of internal functions */ 00087 /*---------------------------------------------------------------------------*/ 00088 00105 Tbl_Table_t * 00106 IoPTableTransformToTable( 00107 Hrc_Model_t *model, 00108 Hrc_Node_t *hnode, 00109 IoPTable_t *pTable) 00110 { 00111 int i, numIo, numIp, numOp; 00112 char *input, *output; 00113 array_t *symCubes, *symCube; 00114 Tbl_Table_t *table; 00115 Var_Variable_t *var; 00116 00117 symCubes = pTable->cubes; 00118 00119 /* if neither symCubes nor default is set, the table is illegal */ 00120 if (symCubes == NIL(array_t) && pTable->defaultOutput == NIL(array_t)){ 00121 error_append("Error: Table "); 00122 error_append(array_fetch(char *,pTable->outputs,0)); 00123 error_append(" has neither relation nor default.\n"); 00124 return NIL(Tbl_Table_t); 00125 } 00126 00127 /* partial check to see if symCubes is properly set up */ 00128 numIp = array_n(pTable->inputs); 00129 numOp = array_n(pTable->outputs); 00130 numIo = numIp + numOp; 00131 if (symCubes != NIL(array_t)){ 00132 for (i=0; i < array_n(symCubes); i++){ 00133 symCube = array_fetch(array_t *,symCubes,i); 00134 if (numIo != array_n(symCube)){ 00135 error_append("Error: The number of columns in the table where output "); 00136 error_append(array_fetch(char *,pTable->outputs,0)); 00137 error_append(" is defined is not equal to the number of input/output variables.\n"); 00138 return NIL(Tbl_Table_t); 00139 } 00140 } 00141 } 00142 00143 table = Tbl_TableAlloc(); 00144 00145 /* add input columns to the table */ 00146 for (i=0; i < array_n(pTable->inputs); i++){ 00147 input = array_fetch(char *,pTable->inputs,i); 00148 /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */ 00149 if ((var = IoVariableFindOrAllocByName(hnode,input)) == NIL(Var_Variable_t)){ 00150 return NIL(Tbl_Table_t); 00151 } 00152 /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */ 00153 if (Tbl_TableAddColumn(table,var,0) == 0){ 00154 return NIL(Tbl_Table_t); 00155 } 00156 } 00157 /* add output columns to the table */ 00158 for (i=0; i < array_n(pTable->outputs); i++){ 00159 output = array_fetch(char *,pTable->outputs,i); 00160 /* the following if should not fail due to the spec of IoVariableFindOrAllocByName() -- To be fixed */ 00161 if ((var = IoVariableFindOrAllocByName(hnode,output)) == NIL(Var_Variable_t)){ 00162 return NIL(Tbl_Table_t); 00163 } 00164 /* the following if should not fail due to the spec of Tbl_TableAddColumn() -- To be fixed */ 00165 if (Tbl_TableAddColumn(table,var,1) == 0){ 00166 return NIL(Tbl_Table_t); 00167 } 00168 } 00169 00170 /* insert a cube one by one to the table */ 00171 if (symCubes != NIL(array_t)){ 00172 for (i=0; i < array_n(symCubes); i++){ 00173 symCube = array_fetch(array_t *,symCubes,i); 00174 if (_IoSymCubeInsertInTable(table, symCube, numIp, numOp) == 0){ 00175 Tbl_TableFree(table); 00176 return NIL(Tbl_Table_t); 00177 } 00178 } 00179 } 00180 00181 /* check if the default and the output has the same number of variables */ 00182 if (pTable->defaultOutput != NIL(array_t) && array_n(pTable->outputs) != array_n(pTable->defaultOutput)){ 00183 error_append("Error: Default is not compatible with the number of outputs in output of "); 00184 error_append(array_fetch(char *,pTable->outputs,0)); 00185 error_append("\n"); 00186 Tbl_TableFree(table); 00187 return NIL(Tbl_Table_t); 00188 } 00189 /* insert the default cube to the table */ 00190 if (_IoDefaultSymCubeInsertInTable(table, pTable->defaultOutput, numOp) == 0) { 00191 Tbl_TableFree(table); 00192 return NIL(Tbl_Table_t); 00193 } 00194 00195 return table; 00196 } 00197 00210 IoSymValue_t * 00211 IoSymValueAlloc(void) 00212 { 00213 return ALLOC(IoSymValue_t,1); 00214 } 00215 00229 void 00230 IoSymValueArrayFree(array_t *valueArray) 00231 { 00232 int i; 00233 00234 for (i=0; i < array_n(valueArray); i++){ 00235 _IoSymValueFree(array_fetch(IoSymValue_t *,valueArray,i)); 00236 } 00237 array_free(valueArray); 00238 } 00239 00240 /*---------------------------------------------------------------------------*/ 00241 /* Definition of static functions */ 00242 /*---------------------------------------------------------------------------*/ 00243 00256 static void 00257 _IoSymValueFree(IoSymValue_t *value) 00258 { 00259 IoSymValueType flag; 00260 00261 /* if flag == IoUniverse_c, we have no extra work to do */ 00262 if ((flag = value->flag) == IoLeaf_c ){ 00263 FREE(value->left); 00264 } 00265 if (flag == IoRange_c){ 00266 FREE(value->left); 00267 FREE(value->right); 00268 } 00269 if (flag == IoComplement_c){ 00270 _IoSymValueFree(value->left); 00271 } 00272 if (flag == IoList_c){ 00273 int i; 00274 IoSymValue_t *valueTmp; 00275 for (i=0; i < array_n(value->elements); i++){ 00276 valueTmp = array_fetch(IoSymValue_t *,value->elements,i); 00277 _IoSymValueFree(valueTmp); 00278 } 00279 array_free(value->elements); 00280 } 00281 if (flag == IoAssign_c){ 00282 FREE(value->left); 00283 } 00284 FREE(value); 00285 } 00286 00303 static int 00304 _IoSymCubeInsertInTable( 00305 Tbl_Table_t *table, 00306 array_t *symCube, 00307 int numIp, 00308 int numOp) 00309 { 00310 int index, i; 00311 IoSymValue_t *symValue; 00312 Tbl_Entry_t *entry; 00313 00314 /* get a new row for the cube */ 00315 index = Tbl_TableAddRow(table); 00316 00317 for (i=0; i < numIp; i++){ 00318 symValue = array_fetch(IoSymValue_t *,symCube,i); 00319 entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,0),table); 00320 if (entry == NIL(Tbl_Entry_t)) 00321 return 0; 00322 Tbl_TableSetEntry(table,entry,index,i,0); 00323 } 00324 for (i=0; i < numOp; i++){ 00325 symValue = array_fetch(IoSymValue_t *,symCube, numIp+i); 00326 entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table); 00327 if (entry == NIL(Tbl_Entry_t)) 00328 return 0; 00329 Tbl_TableSetEntry(table,entry,index,i,1); 00330 } 00331 return 1; 00332 } 00333 00347 static int 00348 _IoDefaultSymCubeInsertInTable( 00349 Tbl_Table_t *table, 00350 array_t *symCube, 00351 int numOp) 00352 { 00353 int i; 00354 IoSymValue_t *symValue; 00355 Tbl_Entry_t *entry; 00356 00357 /* no defaults is asserted. */ 00358 if (symCube == NIL(array_t)){ 00359 return 1; 00360 } 00361 00362 for (i=0; i < array_n(symCube); i++){ 00363 symValue = array_fetch(IoSymValue_t *,symCube, i); 00364 entry = _IoSymValueTransformToEntry(symValue,Tbl_TableReadIndexVar(table,i,1),table); 00365 if (entry == NIL(Tbl_Entry_t)) 00366 return 0; 00367 Tbl_TableDefaultSetEntry(table,entry,i); 00368 } 00369 return 1; 00370 } 00371 00391 static Tbl_Entry_t * 00392 _IoSymValueTransformToEntry( 00393 IoSymValue_t *value, 00394 Var_Variable_t *var, 00395 Tbl_Table_t *table) 00396 { 00397 IoSymValueType flag; 00398 Tbl_Entry_t *entry; 00399 00400 if ((flag = value->flag) == IoLeaf_c){ 00401 int index; 00402 index = VariableReadIndex(var,(char *)(value->left)); 00403 if (index == -1){ 00404 return NIL(Tbl_Entry_t); 00405 } 00406 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00407 Tbl_EntrySetValue(entry,index,index); 00408 return entry; 00409 } 00410 if (flag == IoUniverse_c){ 00411 int range; 00412 range = Var_VariableReadNumValues(var); 00413 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00414 Tbl_EntrySetValue(entry,0,range-1); 00415 return entry; 00416 } 00417 if (flag == IoRange_c){ 00418 int indexFrom, indexTo; 00419 indexFrom = VariableReadIndex(var,(char *)(value->left)); 00420 indexTo = VariableReadIndex(var,(char *)(value->right)); 00421 if (indexFrom == -1 || indexTo == -1){ 00422 return NIL(Tbl_Entry_t); 00423 } 00424 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00425 Tbl_EntrySetValue(entry,indexFrom,indexTo); 00426 return entry; 00427 } 00428 if (flag == IoComplement_c){ 00429 entry = _IoSymValueTransformToEntry(value->left,var,table); 00430 if (entry == NIL(Tbl_Entry_t)){ 00431 return NIL(Tbl_Entry_t); 00432 } 00433 Tbl_EntryComplement(entry,0,Var_VariableReadNumValues(var)-1); 00434 return entry; 00435 } 00436 if (flag == IoList_c){ 00437 int i; 00438 IoSymValue_t *valueTmp; 00439 Tbl_Entry_t *entryTmp, *entryUnion; 00440 00441 entry = Tbl_EntryAlloc(Tbl_EntryNormal_c); 00442 for (i=0; i < array_n(value->elements); i++){ 00443 valueTmp = array_fetch(IoSymValue_t *,value->elements,i); 00444 entryTmp = _IoSymValueTransformToEntry(valueTmp,var,table); 00445 if (entryTmp == NIL(Tbl_Entry_t)){ 00446 Tbl_EntryFree(entry); 00447 return NIL(Tbl_Entry_t); 00448 } 00449 entryUnion = Tbl_EntryMerge(entry,entryTmp); 00450 Tbl_EntryFree(entry); 00451 Tbl_EntryFree(entryTmp); 00452 entry = entryUnion; 00453 } 00454 return entry; 00455 } 00456 if (flag == IoAssign_c){ 00457 int i; 00458 Var_Variable_t *varCandidate = NIL(Var_Variable_t); 00459 00460 entry = Tbl_EntryAlloc(Tbl_EntryEqual_c); 00461 for (i=0; i < Tbl_TableReadNumInputs(table); i++){ 00462 varCandidate = Tbl_TableReadIndexVar(table,i,0); 00463 if (strcmp(Var_VariableReadName(varCandidate),(char *)value->left) == 0){ 00464 /* found the variable referred in = construct as an input of the table */ 00465 break; 00466 } 00467 } 00468 /* the following if-clause is only true when the above for-loop cannot 00469 find the variable referred in = construct */ 00470 if (i == Tbl_TableReadNumInputs(table)){ 00471 error_append("Variable "); 00472 error_append((char *)value->left); 00473 error_append(" is not an input of the table where "); 00474 error_append(Var_VariableReadName(var)); 00475 error_append(" is an output. It cannot be used as an argument of = construct.\n"); 00476 Tbl_EntryFree(entry); 00477 return NIL(Tbl_Entry_t); 00478 } 00479 /* check if the two variables connected with = construct have the same domain */ 00480 if (Var_VariablesTestHaveSameDomain(var,varCandidate) == 0){ 00481 error_append("Variables "); 00482 error_append((char *)value->left); 00483 error_append(" and "); 00484 error_append(Var_VariableReadName(var)); 00485 error_append(" have different domains. Cannot be used in = construct.\n"); 00486 Tbl_EntryFree(entry); 00487 return NIL(Tbl_Entry_t); 00488 } 00489 Tbl_EntrySetEqual(entry,i); 00490 return entry; 00491 } 00492 else { 00493 return NIL(Tbl_Entry_t); 00494 } 00495 } 00496 00497 00498 00499 00514 static int 00515 VariableReadIndex( 00516 Var_Variable_t *var, 00517 char *value) 00518 { 00519 int integer; 00520 if (Var_VariableTestIsEnumerative(var) == 1){ 00521 integer = IoAtoi(value); 00522 if (integer == -1 || integer >= Var_VariableReadNumValues(var)){ 00523 error_append("Value "); 00524 error_append(value); 00525 error_append(" is not a proper value for variable "); 00526 error_append(Var_VariableReadName(var)); 00527 error_append("\n"); 00528 return -1; 00529 } 00530 return integer; 00531 } 00532 /* var is now a symbolic variable */ 00533 if ((integer = Var_VariableReadIndexFromSymbolicValue(var,value)) == -1){ 00534 error_append("Value "); 00535 error_append(value); 00536 error_append(" is not a proper value for variable "); 00537 error_append(Var_VariableReadName(var)); 00538 error_append("\n"); 00539 return -1; 00540 } 00541 return integer; 00542 } 00543 00544 00545 00546 00547 00548 00549 00550 00551 00552 00553 00554