00001
00002
00003 #include "utils.h"
00004 #include "restructs.h"
00005 #include "conversion.h"
00006 #include "configuration.h"
00007
00008 ExprType *dupType(ExprType *ty, Region *r) {
00009 Hashtable *varTable = newHashTable2(100, r);
00010
00011 ExprType *dup = dupTypeAux(ty, r, varTable);
00012 return dup;
00013
00014
00015 }
00016
00017 int typeEqSyntatic(ExprType *a, ExprType *b) {
00018 if(getNodeType(a)!=getNodeType(b) || getVararg(a) != getVararg(b)) {
00019 return 0;
00020 }
00021 switch(getNodeType(a)) {
00022 case T_CONS:
00023 case T_TUPLE:
00024 if(T_CONS_ARITY(a) == T_CONS_ARITY(b) &&
00025 (getNodeType(a) == T_TUPLE || strcmp(T_CONS_TYPE_NAME(a), T_CONS_TYPE_NAME(b)) == 0)) {
00026 int i;
00027 for(i=0;i<T_CONS_ARITY(a);i++) {
00028 if(!typeEqSyntatic(T_CONS_TYPE_ARG(a, i),T_CONS_TYPE_ARG(b, i))) {
00029 return 0;
00030 }
00031 }
00032 return 1;
00033 }
00034 return 0;
00035 case T_VAR:
00036 return T_VAR_ID(a) == T_VAR_ID(b);
00037 case T_IRODS:
00038 return strcmp(a->text, b->text) == 0;
00039 default:
00040 return 1;
00041 }
00042
00043 }
00044
00045 ExprType *dupTypeAux(ExprType *ty, Region *r, Hashtable *varTable) {
00046 ExprType **paramTypes;
00047 int i;
00048 ExprType *newt;
00049 ExprType *exist;
00050 char *name;
00051 char buf[128];
00052 switch(getNodeType(ty)) {
00053 case T_CONS:
00054 paramTypes = (ExprType **) region_alloc(r,sizeof(ExprType *)*T_CONS_ARITY(ty));
00055 for(i=0;i<T_CONS_ARITY(ty);i++) {
00056 paramTypes[i] = dupTypeAux(T_CONS_TYPE_ARG(ty, i),r,varTable);
00057 }
00058 newt = newConsType(T_CONS_ARITY(ty), T_CONS_TYPE_NAME(ty), paramTypes, r);
00059 newt->option = ty->option;
00060 break;
00061 case T_TUPLE:
00062 paramTypes = (ExprType **) region_alloc(r,sizeof(ExprType *)*T_CONS_ARITY(ty));
00063 for(i=0;i<T_CONS_ARITY(ty);i++) {
00064 paramTypes[i] = dupTypeAux(T_CONS_TYPE_ARG(ty, i),r,varTable);
00065 }
00066 newt = newTupleType(T_CONS_ARITY(ty), paramTypes, r);
00067 newt->option = ty->option;
00068 break;
00069 case T_VAR:
00070 name = getTVarName(T_VAR_ID(ty), buf);
00071 exist = (ExprType *)lookupFromHashTable(varTable, name);
00072 if(exist != NULL)
00073 newt = exist;
00074 else {
00075 newt = newTVar2(T_VAR_NUM_DISJUNCTS(ty), T_VAR_DISJUNCTS(ty), r);
00076 insertIntoHashTable(varTable, name, newt);
00077
00078 }
00079 newt->option = ty->option;
00080 break;
00081 case T_FLEX:
00082 paramTypes = (ExprType **) region_alloc(r,sizeof(ExprType *)*1);
00083 paramTypes[0] = dupTypeAux(ty->subtrees[0],r,varTable);
00084 newt = newExprType(T_FLEX, 1, paramTypes, r);
00085 newt->option = ty->option;
00086 break;
00087
00088 default:
00089 newt = ty;
00090 break;
00091 }
00092 return newt;
00093 }
00094 int coercible(ExprType *a, ExprType *b) {
00095 return (getNodeType(a)!=T_CONS && getNodeType(a) == getNodeType(b)) ||
00096 (getNodeType(b) == T_DOUBLE && getNodeType(a) == T_INT) ||
00097 (getNodeType(b) == T_DOUBLE && getNodeType(a) == T_STRING) ||
00098 (getNodeType(b) == T_INT && getNodeType(a) == T_DOUBLE) ||
00099 (getNodeType(b) == T_INT && getNodeType(a) == T_STRING) ||
00100 (getNodeType(b) == T_STRING && getNodeType(a) == T_INT) ||
00101 (getNodeType(b) == T_STRING && getNodeType(a) == T_DOUBLE) ||
00102 (getNodeType(b) == T_STRING && getNodeType(a) == T_BOOL) ||
00103 (getNodeType(b) == T_BOOL && getNodeType(a) == T_STRING) ||
00104 (getNodeType(b) == T_DATETIME && getNodeType(a) == T_INT) ||
00105 (getNodeType(b) == T_DATETIME && getNodeType(a) == T_DOUBLE) ||
00106 (getNodeType(b) == T_DYNAMIC) ||
00107 (getNodeType(a) == T_DYNAMIC) ||
00108 (getNodeType(a)==T_CONS && getNodeType(b)==T_CONS && coercible(T_CONS_TYPE_ARG(a, 0), T_CONS_TYPE_ARG(b, 0)));
00109 }
00110
00111
00112
00113 ExprType* unifyTVarL(ExprType *type, ExprType* expected, Hashtable *varTypes, Region *r) {
00114 char buf[128];
00115 if(T_VAR_NUM_DISJUNCTS(type)==0) {
00116 if(occursIn(type, expected)) {
00117 return NULL;
00118 }
00119 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(type), buf), expected);
00120 return dereference(expected, varTypes, r);
00121 } else {
00122 int i;
00123 ExprType *ty = NULL;
00124 for(i=0;i<T_VAR_NUM_DISJUNCTS(type);i++) {
00125 if(getNodeType(T_VAR_DISJUNCT(type,i)) == getNodeType(expected)) {
00126 ty = expected;
00127 break;
00128 }
00129 }
00130 if(ty != NULL) {
00131 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(type), buf), expected);
00132 }
00133 return ty;
00134 }
00135
00136 }
00137 ExprType* unifyTVarR(ExprType *type, ExprType* expected, Hashtable *varTypes, Region *r) {
00138 char buf[128];
00139 if(T_VAR_NUM_DISJUNCTS(expected)==0) {
00140 if(occursIn(expected, type)) {
00141 return NULL;
00142 }
00143 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), type);
00144 return dereference(expected, varTypes, r);
00145 } else {
00146 int i;
00147 ExprType *ty = NULL;
00148 for(i=0;i<T_VAR_NUM_DISJUNCTS(expected);i++) {
00149 if(getNodeType(type) == getNodeType(T_VAR_DISJUNCT(expected,i))) {
00150 ty = type;
00151 }
00152 }
00153 if(ty != NULL) {
00154 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), ty);
00155 return dereference(expected, varTypes, r);
00156 }
00157 return ty;
00158 }
00159
00160 }
00161
00162
00163
00164
00165 ExprType* unifyWith(ExprType *type, ExprType* expected, Hashtable *varTypes, Region *r) {
00166 if(getVararg(type) != getVararg(expected)) {
00167 return NULL;
00168 }
00169 char buf[128];
00170
00171
00172
00173 type = dereference(type, varTypes, r);
00174 expected = dereference(expected, varTypes, r);
00175 if(getNodeType(type) == T_UNSPECED) {
00176 return expected;
00177 }
00178 if(getNodeType(expected) == T_DYNAMIC) {
00179 return type;
00180 }
00181 if(getNodeType(type) == T_VAR && getNodeType(expected) == T_VAR) {
00182 if(T_VAR_ID(type) == T_VAR_ID(expected)) {
00183
00184 return type;
00185 } else if(T_VAR_NUM_DISJUNCTS(type) > 0 && T_VAR_NUM_DISJUNCTS(expected) > 0) {
00186 Node *c[10];
00187 Node** cp = c;
00188 int i,k;
00189 for(k=0;k<T_VAR_NUM_DISJUNCTS(expected);k++) {
00190 for(i=0;i<T_VAR_NUM_DISJUNCTS(type);i++) {
00191 if(getNodeType(T_VAR_DISJUNCT(type,i)) == getNodeType(T_VAR_DISJUNCT(expected,k))) {
00192 *(cp++)=T_VAR_DISJUNCT(expected,k);
00193 break;
00194 }
00195 }
00196 }
00197 if(cp == c) {
00198 return NULL;
00199 } else {
00200 ExprType *gcd;
00201 if(cp-c==1) {
00202 gcd = *c;
00203 } else {
00204 gcd = newTVar2(cp-c, c, r);
00205 }
00206 updateInHashTable(varTypes, getTVarName(T_VAR_ID(type), buf), gcd);
00207 updateInHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), gcd);
00208 return gcd;
00209 }
00210 } else {
00211 if(T_VAR_NUM_DISJUNCTS(type)==0) {
00212 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(type), buf), expected);
00213 return dereference(expected, varTypes, r);
00214 } else if(T_VAR_NUM_DISJUNCTS(expected)==0) {
00215 insertIntoHashTable(varTypes, getTVarName(T_VAR_ID(expected), buf), type);
00216 return dereference(expected, varTypes, r);
00217 } else {
00218
00219 return NULL;
00220 }
00221 }
00222 } else
00223 if(getNodeType(type) == T_VAR) {
00224 return unifyTVarL(type, expected, varTypes, r);
00225 } else if(getNodeType(expected) == T_VAR) {
00226 return unifyTVarR(type, expected, varTypes, r);
00227 } else {
00228 return unifyNonTvars(type, expected, varTypes, r);
00229 }
00230 }
00231
00232
00233
00234
00235
00236 ExprType* unifyNonTvars(ExprType *type, ExprType *expected, Hashtable *varTypes, Region *r) {
00237 if(getNodeType(type) == T_CONS && getNodeType(expected) == T_CONS) {
00238 if(strcmp(T_CONS_TYPE_NAME(type), T_CONS_TYPE_NAME(expected)) == 0
00239 && T_CONS_ARITY(type) == T_CONS_ARITY(expected)) {
00240 ExprType **subtrees = (ExprType **) region_alloc(r, sizeof(ExprType *) * T_CONS_ARITY(expected));
00241
00242 int i;
00243 for(i=0;i<T_CONS_ARITY(type);i++) {
00244 ExprType *elemType = unifyWith(
00245 T_CONS_TYPE_ARG(type, i),
00246 T_CONS_TYPE_ARG(expected, i),
00247 varTypes,r);
00248 if(elemType == NULL) {
00249 return NULL;
00250 }
00251 subtrees[i] = elemType;
00252 }
00253 return dereference(newConsType(T_CONS_ARITY(expected), T_CONS_TYPE_NAME(expected), subtrees, r), varTypes, r);
00254 } else {
00255 return NULL;
00256 }
00257 } else if(getNodeType(type) == T_IRODS || getNodeType(expected) == T_IRODS) {
00258 if(strcmp(type->text, expected->text)!=0) {
00259 return NULL;
00260 }
00261 return expected;
00262 } else if(getNodeType(expected) == getNodeType(type)) {
00263 return expected;
00264 } else {
00265 return newErrorType(RE_TYPE_ERROR, r);
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 char* getTVarName(int vid, char name[128]) {
00283 snprintf(name, 128, "?%d",vid);
00284 return name;
00285 }
00286 char* getTVarNameRegion(int vid, Region *r) {
00287 char *name = (char *) region_alloc(r, sizeof(char)*128);
00288 snprintf(name, 128, "?%d",vid);
00289 return name;
00290 }
00291 char* getTVarNameRegionFromExprType(ExprType *tvar, Region *r) {
00292 return getTVarNameRegion(T_VAR_ID(tvar), r);
00293 }
00294
00295
00296 int newTVarId() {
00297 return ruleEngineConfig.tvarNumber ++;
00298 }
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 char *cpString(char *str, Region *r) {
00335 if(IN_REGION(str, r)) {
00336 return str;
00337 } else
00338 return cpStringExt(str, r);
00339 }
00340 char *cpStringExt(char *str, Region *r) {
00341 char *strCp = (char *)region_alloc(r, (strlen(str)+1) * sizeof(char) );
00342 strcpy(strCp, str);
00343 return strCp;
00344 }
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 void cpHashtable(Hashtable *env, Region *r) {
00367 int i;
00368
00369 for(i=0;i<env->size;i++) {
00370 struct bucket *b = env->buckets[i];
00371 while(b!=NULL) {
00372 b->value = cpRes((Res *)b->value, r);
00373 b= b->next;
00374 }
00375 }
00376 }
00377
00378 void cpEnv(Env *env, Region *r) {
00379 cpHashtable(env->current, r);
00380 if(env->previous!=NULL) {
00381 cpEnv(env->previous, r);
00382 }
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420 char *cpString2(char *str, Region *oldr, Region *r) {
00421 if(!IN_REGION(str, oldr)) {
00422 return str;
00423 } else
00424 return cpStringExt(str, r);
00425 }
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447 void cpHashtable2(Hashtable *env, Region *oldr, Region *r) {
00448 int i;
00449
00450 for(i=0;i<env->size;i++) {
00451 struct bucket *b = env->buckets[i];
00452 while(b!=NULL) {
00453 b->value = cpRes2((Res *)b->value, oldr, r);
00454 b= b->next;
00455 }
00456 }
00457 }
00458
00459 void cpEnv2(Env *env, Region *oldr, Region *r) {
00460 cpHashtable2(env->current, oldr, r);
00461 if(env->previous!=NULL) {
00462 cpEnv2(env->previous, oldr, r);
00463 }
00464 }
00465
00466 Res *setVariableValue(char *varName, Res *val, ruleExecInfo_t *rei, Env *env, rError_t *errmsg, Region *r) {
00467 int i;
00468 char *varMap;
00469 char errbuf[ERR_MSG_LEN];
00470 if (varName[0] == '$') {
00471 if(TYPE(val)!=T_STRING) {
00472 snprintf(errbuf, ERR_MSG_LEN, "error: assign a nonstring value to session variable %s.", varName);
00473 addRErrorMsg(errmsg, RE_UNSUPPORTED_OP_OR_TYPE, errbuf);
00474 return newErrorRes(r, RE_UNSUPPORTED_OP_OR_TYPE);
00475 }
00476 i = getVarMap("", varName, &varMap, 0);
00477 if (i < 0) {
00478 snprintf(errbuf, ERR_MSG_LEN, "error: unsupported session variable \"%s\".",varName);
00479 addRErrorMsg(errmsg, RE_UNSUPPORTED_SESSION_VAR, errbuf);
00480 return newErrorRes(r, RE_UNSUPPORTED_SESSION_VAR);
00481 }
00482 setVarValue(varMap, rei, strdup(val->text));
00483 return newIntRes(r, 0);
00484 }
00485 else if(varName[0] == '*') {
00486 if(lookupFromEnv(env, varName)==NULL) {
00487
00488 if(insertIntoHashTable(env->current, varName, val) == 0) {
00489 snprintf(errbuf, ERR_MSG_LEN, "error: unable to write to local variable \"%s\".",varName);
00490 addRErrorMsg(errmsg, RE_UNABLE_TO_WRITE_LOCAL_VAR, errbuf);
00491 return newErrorRes(r, RE_UNABLE_TO_WRITE_LOCAL_VAR);
00492 }
00493 } else {
00494 updateInEnv(env, varName, val);
00495 }
00496 return newIntRes(r, 0);
00497 }
00498 return newIntRes(r, 0);
00499 }
00500
00501 void printType(ExprType *type, Hashtable *var_types) {
00502 char buf[1024];
00503 typeToString(type, var_types, buf, 1024);
00504 printf("%s", buf);
00505 }
00506
00507 char* typeToString(ExprType *type, Hashtable *var_types, char *buf, int bufsize) {
00508 buf[0] = '\0';
00509 Region *r = make_region(0, NULL);
00510 if(getVararg(type) != OPTION_VARARG_ONCE) {
00511 snprintf(buf+strlen(buf), bufsize-strlen(buf), "vararg ");
00512 }
00513 ExprType *etype = type;
00514 if(getNodeType(etype) == T_VAR && var_types != NULL) {
00515
00516 etype = dereference(etype, var_types, r);
00517 }
00518
00519 if(getNodeType(etype) == T_VAR) {
00520 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", etype == NULL?"?":typeName_ExprType(etype));
00521 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%d", T_VAR_ID(etype));
00522 if(T_VAR_NUM_DISJUNCTS(type)!=0) {
00523 snprintf(buf+strlen(buf), bufsize-strlen(buf), "{");
00524 int i;
00525 for(i=0;i<T_VAR_NUM_DISJUNCTS(type);i++) {
00526 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", typeName_ExprType(T_VAR_DISJUNCT(type, i)));
00527 }
00528 snprintf(buf+strlen(buf), bufsize-strlen(buf), "}");
00529 }
00530 } else if(getNodeType(etype) == T_CONS) {
00531 if(strcmp(etype->text, FUNC) == 0) {
00532 snprintf(buf+strlen(buf), bufsize-strlen(buf), "(");
00533 typeToString(T_CONS_TYPE_ARG(etype, 0), var_types, buf+strlen(buf), bufsize-strlen(buf));
00534 snprintf(buf+strlen(buf), bufsize-strlen(buf), ")");
00535 snprintf(buf+strlen(buf), bufsize-strlen(buf), "->");
00536 typeToString(T_CONS_TYPE_ARG(etype, 1), var_types, buf+strlen(buf), bufsize-strlen(buf));
00537 } else {
00538
00539 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", T_CONS_TYPE_NAME(etype));
00540 int i;
00541 if(T_CONS_ARITY(etype) != 0) {
00542 snprintf(buf+strlen(buf), bufsize-strlen(buf), "(");
00543 for(i=0;i<T_CONS_ARITY(etype);i++) {
00544 if(i!=0) {
00545 snprintf(buf+strlen(buf), bufsize-strlen(buf), ", ");
00546 }
00547 typeToString(T_CONS_TYPE_ARG(etype, i), var_types, buf+strlen(buf), bufsize-strlen(buf));
00548 }
00549 snprintf(buf+strlen(buf), bufsize-strlen(buf), ")");
00550 }
00551 }
00552 } else if(getNodeType(etype) == T_FLEX) {
00553 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", typeName_ExprType(etype));
00554 typeToString(etype->subtrees[0], var_types, buf+strlen(buf), bufsize-strlen(buf));
00555 } else if(getNodeType(etype) == T_FIXD) {
00556 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", typeName_ExprType(etype));
00557 typeToString(etype->subtrees[0], var_types, buf+strlen(buf), bufsize-strlen(buf));
00558 snprintf(buf+strlen(buf), bufsize-strlen(buf), "=> ");
00559 typeToString(etype->subtrees[1], var_types, buf+strlen(buf), bufsize-strlen(buf));
00560 } else if(getNodeType(etype) == T_TUPLE) {
00561 if(T_CONS_ARITY(etype) == 0) {
00562 snprintf(buf+strlen(buf), bufsize-strlen(buf), "unit");
00563 } else {
00564 if(T_CONS_ARITY(etype) == 1) {
00565 snprintf(buf+strlen(buf), bufsize-strlen(buf), "(");
00566 }
00567 int i;
00568 for(i=0;i<T_CONS_ARITY(etype);i++) {
00569 if(i!=0) {
00570 snprintf(buf+strlen(buf), bufsize-strlen(buf), " * ");
00571 }
00572 typeToString(T_CONS_TYPE_ARG(etype, i), var_types, buf+strlen(buf), bufsize-strlen(buf));
00573 }
00574 if(T_CONS_ARITY(etype) == 1) {
00575 snprintf(buf+strlen(buf), bufsize-strlen(buf), ")");
00576 }
00577 }
00578 } else {
00579 snprintf(buf+strlen(buf), bufsize-strlen(buf), "%s ", etype == NULL?"?":typeName_ExprType(etype));
00580 }
00581
00582 int i = strlen(buf) - 1;
00583 while(buf[i]==' ') i--;
00584 buf[i+1]='\0';
00585
00586 region_free(r);
00587 return buf;
00588
00589 }
00590 void typingConstraintsToString(List *typingConstraints, Hashtable *var_types, char *buf, int bufsize) {
00591 char buf2[1024];
00592 char buf3[1024];
00593 ListNode *p = typingConstraints->head;
00594 buf[0] = '\0';
00595 while(p!=NULL) {
00596 snprintf(buf + strlen(buf), bufsize-strlen(buf), "%s<%s\n",
00597 typeToString(TC_A((TypingConstraint *)p->value), NULL, buf2, 1024),
00598 typeToString(TC_B((TypingConstraint *)p->value), NULL, buf3, 1024));
00599 p=p->next;
00600 }
00601 }
00602 ExprType *dereference(ExprType *type, Hashtable *type_table, Region *r) {
00603 if(getNodeType(type) == T_VAR) {
00604 char name[128];
00605 getTVarName(T_VAR_ID(type), name);
00606
00607 ExprType *deref = (ExprType *)lookupFromHashTable(type_table, name);
00608 if(deref == NULL)
00609 return type;
00610 else
00611 return dereference(deref, type_table, r);
00612 }
00613 return type;
00614 }
00615
00616 ExprType *instantiate(ExprType *type, Hashtable *type_table, int replaceFreeVars, Region *r) {
00617 ExprType **paramTypes;
00618 int i;
00619 ExprType *typeInst;
00620 int changed = 0;
00621
00622 switch(getNodeType(type)) {
00623 case T_VAR:
00624 typeInst = dereference(type, type_table, r);
00625 if(typeInst == type) {
00626 return replaceFreeVars?newSimpType(T_UNSPECED, r): type;
00627 } else {
00628 return instantiate(typeInst, type_table, replaceFreeVars, r);
00629 }
00630 default:
00631 if(type->degree != 0) {
00632 paramTypes = (ExprType **) region_alloc(r,sizeof(ExprType *)*type->degree);
00633 for(i=0;i<type->degree;i++) {
00634 paramTypes[i] = instantiate(type->subtrees[i], type_table, replaceFreeVars, r);
00635 if(paramTypes[i]!=type->subtrees[i]) {
00636 changed = 1;
00637 }
00638 }
00639 }
00640 if(changed) {
00641 ExprType *inst = (ExprType *) region_alloc(r, sizeof(ExprType));
00642 memcpy(inst, type, sizeof(ExprType));
00643 inst->subtrees = paramTypes;
00644 return inst;
00645 } else {
00646 return type;
00647 }
00648
00649 }
00650 }
00651
00652
00653 int writeToTmp(char *fileName, char *text) {
00654 char buf[1024];
00655 strcpy(buf, "/tmp/");
00656 strcat(buf, fileName);
00657 FILE *fp = fopen(buf, "a");
00658 if(fp==NULL) {
00659 return 0;
00660 }
00661 fputs(text, fp);
00662 fclose(fp);
00663 return 1;
00664 }
00665 int writeIntToTmp(char *fileName, int text) {
00666 char buf[1024];
00667 snprintf(buf, 1024, "%d", text);
00668 writeToTmp(fileName, buf);
00669 return 1;
00670 }
00671
00672 void printEnvToStdOut(Env *env) {
00673 Env *e = env;
00674 char buffer[1024];
00675 while(e!=NULL) {
00676 if(e!=env)
00677 printf("%s\n===========\n", buffer);
00678 printHashtable(e->current, buffer);
00679 e = e->previous;
00680 }
00681
00682
00683
00684
00685
00686
00687
00688
00689
00690
00691 }
00692
00693 void printVarTypeEnvToStdOut(Hashtable *env) {
00694 int i;
00695 for(i=0;i<env->size;i++) {
00696 struct bucket *b = env->buckets[i];
00697 while(b!=NULL) {
00698 printf("%s=",b->key);
00699 printType((ExprType *)b->value, NULL);
00700 printf("\n");
00701 b=b->next;
00702 }
00703 }
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726 Env* globalEnv(Env *env) {
00727 Env *global = env;
00728 while(global->previous!=NULL) {
00729 global = global->previous;
00730 }
00731 return global;
00732 }
00733
00734
00735 void listAppendNoRegion(List *list, void *value) {
00736 ListNode *ln = newListNodeNoRegion(value);
00737 if(list->head != NULL) {
00738 list->tail = list->tail->next = ln;
00739 } else {
00740 list->head = list->tail = ln;
00741 }
00742 }
00743 void listAppend(List *list, void *value, Region *r) {
00744 ListNode *ln = newListNode(value, r);
00745 if(list->head != NULL) {
00746 list->tail = list->tail->next = ln;
00747 } else {
00748 list->head = list->tail = ln;
00749 }
00750 }
00751
00752 void listAppendToNode(List *list, ListNode *node, void *value, Region *r) {
00753 ListNode *ln = newListNode(value, r);
00754 if(node->next != NULL) {
00755 ln->next = node->next;
00756 node->next = ln;
00757 } else {
00758 node->next = list->tail = ln;
00759 }
00760 }
00761
00762 void listRemove(List *list, ListNode *node) {
00763 ListNode *prev = NULL, *curr = list->head;
00764 while(curr != NULL) {
00765 if(curr == node) {
00766 if(prev == NULL) {
00767 list->head = node->next;
00768 } else {
00769 prev->next = node->next;
00770 }
00771
00772 break;
00773 }
00774 prev = curr;
00775 curr = curr->next;
00776 }
00777 if(list->tail == node) {
00778 list->tail = prev;
00779 }
00780
00781 }
00782 void listRemoveNoRegion(List *list, ListNode *node) {
00783 ListNode *prev = NULL, *curr = list->head;
00784 while(curr != NULL) {
00785 if(curr == node) {
00786 if(prev == NULL) {
00787 list->head = node->next;
00788 } else {
00789 prev->next = node->next;
00790 }
00791 free(node);
00792 break;
00793 }
00794 prev = curr;
00795 curr = curr->next;
00796 }
00797 if(list->tail == node) {
00798 list->tail = prev;
00799 }
00800
00801 }
00802
00803 int appendToByteBufNew(bytesBuf_t *bytesBuf, char *str) {
00804 int i,j;
00805 char *tBuf;
00806
00807 i = strlen(str);
00808 j = 0;
00809 if (bytesBuf->buf == NULL) {
00810 bytesBuf->buf = malloc (i + 1 + MAX_NAME_LEN * 5);
00811 memset(bytesBuf->buf, 0, i + 1 + MAX_NAME_LEN * 5);
00812 strcpy((char *)bytesBuf->buf, str);
00813 bytesBuf->len = i + 1 + MAX_NAME_LEN * 5;
00814 }
00815 else {
00816 j = strlen((char *)bytesBuf->buf);
00817 if ((i + j) < bytesBuf->len) {
00818 strcat((char *)bytesBuf->buf, str);
00819 }
00820 else {
00821 tBuf = (char *) malloc(j + i + 1 + (MAX_NAME_LEN * 5));
00822 strcpy(tBuf,(char *)bytesBuf->buf);
00823 strcat(tBuf,str);
00824 free (bytesBuf->buf);
00825 bytesBuf->len = j + i + 1 + (MAX_NAME_LEN * 5);
00826 bytesBuf->buf = tBuf;
00827 }
00828 }
00829 return 0;
00830 }
00831
00832 void logErrMsg(rError_t *errmsg, rError_t *system) {
00833 char errbuf[ERR_MSG_LEN * 16];
00834 errMsgToString(errmsg, errbuf, ERR_MSG_LEN * 16);
00835 #ifdef DEBUG
00836 writeToTmp("err.log", "begin errlog\n");
00837 writeToTmp("err.log", errbuf);
00838 writeToTmp("err.log", "end errlog\n");
00839 #endif
00840 if(system!=NULL) {
00841 rodsLogAndErrorMsg(LOG_ERROR, system, RE_UNKNOWN_ERROR, "%s", errbuf);
00842 } else {
00843 rodsLog (LOG_ERROR, "%s", errbuf);
00844 }
00845 }
00846
00847 char *errMsgToString(rError_t *errmsg, char *errbuf, int buflen ) {
00848 errbuf[0] = '\0';
00849 int p = 0;
00850 int i;
00851 int first = 1;
00852 int restart = 0;
00853 for(i=errmsg->len-1;i>=0;i--) {
00854 if(strcmp(errmsg->errMsg[i]->msg, ERR_MSG_SEP) == 0) {
00855 if(first || restart)
00856 continue;
00857 else {
00858 restart = 1;
00859 continue;
00860 }
00861 }
00862 if(restart) {
00863 snprintf(errbuf+p, buflen-p, "%s\n", ERR_MSG_SEP);
00864 p += strlen(errbuf+p);
00865 }
00866 if(!first && !restart) {
00867 snprintf(errbuf+p, buflen-p, "caused by: %s\n", errmsg->errMsg[i]->msg);
00868 } else {
00869 snprintf(errbuf+p, buflen-p, "%s\n", errmsg->errMsg[i]->msg);
00870 first = 0;
00871 restart = 0;
00872
00873 }
00874 p += strlen(errbuf+p);
00875 }
00876 return errbuf;
00877
00878 }
00879
00880 void *lookupFromEnv(Env *env, char *key) {
00881 void* val = lookupFromHashTable(env->current, key);
00882 if(val==NULL && env->previous!=NULL) {
00883 val = lookupFromEnv(env->previous, key);
00884 }
00885 return val;
00886 }
00887
00888 void updateInEnv(Env *env, char *varName, Res *res) {
00889 Env *defined = env;
00890
00891 while(defined != NULL && lookupFromHashTable(defined->current, varName) == NULL) {
00892 defined = defined ->previous;
00893 }
00894 if(defined != NULL) {
00895 updateInHashTable(defined->current, varName, res);
00896 } else {
00897 insertIntoHashTable(env->current, varName, res);
00898 }
00899 }
00900
00901 void freeEnvUninterpretedStructs(Env *e) {
00902 Hashtable *ht = e->current;
00903 int i;
00904 for(i=0;i<ht->size;i++) {
00905 struct bucket *b = ht->buckets[i];
00906 while(b!=NULL) {
00907 Res *res = (Res *) b->value;
00908 if(TYPE(res) == T_IRODS) {
00909 if(RES_UNINTER_STRUCT(res)!=NULL) {
00910 free(RES_UNINTER_STRUCT(res));
00911 }
00912 if(RES_UNINTER_BUFFER(res)!=NULL) {
00913 free(RES_UNINTER_BUFFER(res));
00914 }
00915 }
00916 b=b->next;
00917 }
00918 }
00919 if(e->previous!=NULL) {
00920 freeEnvUninterpretedStructs(e->previous);
00921 }
00922 }
00923 int isPattern(Node *pattern) {
00924
00925 if(getNodeType(pattern) == N_APPLICATION || getNodeType(pattern) == N_TUPLE) {
00926 int i;
00927 for(i=0;i<pattern->degree;i++) {
00928 if(!isPattern(pattern->subtrees[i]))
00929 return 0;
00930 }
00931 return 1;
00932 } else if(getNodeType(pattern) == TK_TEXT || getNodeType(pattern) == TK_VAR || getNodeType(pattern) == TK_STRING
00933 || getNodeType(pattern) == TK_BOOL || getNodeType(pattern) == TK_INT || getNodeType(pattern) == TK_DOUBLE) {
00934 return 1;
00935 } else {
00936 return 0;
00937
00938 }
00939 }
00940
00941 int isRecursive(Node *rule) {
00942 return invokedIn(rule->subtrees[0]->text, rule->subtrees[1]) ||
00943 invokedIn(rule->subtrees[0]->text, rule->subtrees[2]) ||
00944 invokedIn(rule->subtrees[0]->text, rule->subtrees[3]);
00945
00946 }
00947
00948 int invokedIn(char *fn, Node *expr) {
00949 int i;
00950 switch(getNodeType(expr)) {
00951 case TK_TEXT:
00952 if(strcmp(expr->text, fn) == 0) {
00953 return 1;
00954 }
00955 break;
00956
00957 case N_APPLICATION:
00958 case N_ACTIONS:
00959 case N_ACTIONS_RECOVERY:
00960 for(i=0;i<expr->degree;i++) {
00961 if(invokedIn(fn, expr->subtrees[i])) {
00962 return 1;
00963 }
00964 }
00965 break;
00966 default:
00967 break;
00968 }
00969
00970 return 0;
00971 }
00972 Node *lookupAVUFromMetadata(Node *metadata, char *a) {
00973 int i;
00974 for(i=0;i<metadata->degree;i++) {
00975 if(strcmp(metadata->subtrees[i]->subtrees[0]->text, a) == 0) {
00976 return metadata->subtrees[i];
00977 }
00978 }
00979 return NULL;
00980
00981 }
00982
00983 int isRuleGenSyntax(char *expr) {
00984 char *p = expr;
00985 int mode = 0;
00986 while(*p != '\0') {
00987 switch(mode) {
00988 case 0:
00989 if(*p=='#' && *(p+1)=='#') {
00990 return 0;
00991 } else if(*p=='#') {
00992 mode = 1;
00993 } else if(*p=='\'') {
00994 mode = 2;
00995 } else if(*p=='\"') {
00996 mode = 3;
00997 } else if(*p=='`') {
00998 mode = 4;
00999 }
01000 break;
01001 case 1:
01002 if(*p=='\n') {
01003 mode = 0;
01004 }
01005 break;
01006 case 2:
01007 if(*p=='\\') {
01008 p++;
01009 if(*p=='\0') {
01010 break;
01011 }
01012 } else if(*p == '\'') {
01013 mode = 0;
01014 }
01015 break;
01016 case 3:
01017 if(*p=='\\') {
01018 p++;
01019 if(*p=='\0') {
01020 break;
01021 }
01022 } else if(*p == '\"') {
01023 mode = 0;
01024 }
01025 break;
01026 case 4:
01027 if(*p == '`' && *(p+1) == '`') {
01028 p++;
01029 mode = 0;
01030 }
01031 break;
01032 }
01033 p++;
01034 }
01035 return 1;
01036 }
01037 #define KEY_INSTANCE
01038 #include "key.instance.h"
01039 #include "restruct.templates.h"
01040 #include "end.instance.h"
01041 void keyNode(Node *node, char *keyBuf) {
01042
01043 if(node->degree>0) {
01044 snprintf(keyBuf, KEY_SIZE, "%p", node);
01045 } else {
01046 char *p = keyBuf;
01047 int len = snprintf(p, KEY_SIZE, "node::%d::%p::%lld::%p::%d::%s::%s::%d::%f::%lld::%p::%p::%p",
01048 node->option, node->coercionType, node->expr, node->exprType,
01049 (int)node->nodeType, node->base, node->text, node->ival, node->dval, node->lval, node->func, node->ruleIndexList, node->param
01050 );
01051 if(len >= KEY_SIZE) {
01052 snprintf(keyBuf, KEY_SIZE, "pointer::%p", node);
01053 return;
01054 }
01055 }
01056 }
01057 void keyBuf(unsigned char *buf, int size, char *keyBuf) {
01058 if(size * 2 + 1 <= KEY_SIZE) {
01059 char *p = keyBuf;
01060 for(int i=0;i<size;i++) {
01061 *(p++) = 'A' + (buf[i] & (unsigned char) 0xf);
01062 *(p++) = 'A' + (buf[i] & (unsigned char) 0xf0);
01063 }
01064 *(p++) = '\0';
01065 } else {
01066 snprintf(keyBuf, KEY_SIZE, "pointer::%p", buf);
01067
01068 }
01069 }
01070 #undef KEY_INSTANCE
01071
01072 #include "region.to.region.instance.h"
01073 #include "restruct.templates.h"
01074 #include "end.instance.h"
01075
01076 #include "region.to.region2.instance.h"
01077 #include "restruct.templates.h"
01078 #include "end.instance.h"
01079
01080 #include "to.region.instance.h"
01081 #include "restruct.templates.h"
01082 #include "end.instance.h"
01083
01084 #include "to.memory.instance.h"
01085 #include "restruct.templates.h"
01086 #include "end.instance.h"