/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include #include "interact.h" #include #define MAXNAME 20 #define MAXRANK 16 static Object membernames(Object); static Object fillnull(Object *,Object ); static Error cullout(Object *,Object *); static int ismatch(Object , char *); /* * SelectorList support added 3/3/95 - dawood */ #define SELECTOR_LIST_SUPPORT #if !defined(SELECTOR_LIST_SUPPORT) static Error dolist(Object , Object *, int ,struct einfo *, int); #else static int getmatches(Object , Object, int**); static Error dolist(Object , Object *, int ,struct einfo *, int*, int ); #endif static Object zerobase(int ,int); static int getsize(Object); extern int EndCheck(char *,char *); static int selector_driver(Object *in, Object *out, int allowLists); int m_SelectorList(Object *in, Object *out) { return selector_driver(in,out,1); } m_Selector(Object *in, Object *out) { return selector_driver(in,out,0); } static int selector_driver(Object *in, Object *out, int allowLists) { struct einfo ei; int i,n,change3,change4,index; char *id, *label; Object idobj,vallist,strlist,newlist; Class class; char *string,*cstring; int item1,item2,icull,startlist,msglen=0,shape[MAXRANK]; Type type1; int needfree=0; #if defined(SELECTOR_LIST_SUPPORT) int match_count = 0, *matched_indices = NULL; #endif ei.msgbuf = NULL; strlist = NULL; vallist = NULL; out[0] = NULL; out[1] = NULL; /* get id */ if (!DXExtractString(in[0], &id)){ DXSetError(ERROR_BAD_PARAMETER,"#10000","id"); return ERROR; } idobj = in[0]; /* read current string */ if (in[1]){ if (!DXExtractNthString(in[1],0,&cstring)) DXErrorGoto(ERROR_INTERNAL, "current value must be string or string list"); } else index=0; /* read cull parameter */ if (in[5]){ if (!DXExtractInteger(in[5],&icull) || icull>1 || icull<0){ DXSetError(ERROR_BAD_PARAMETER,"#10070","cull"); return ERROR; } } else icull=0; /* read label */ if (in[6]){ if (!DXExtractString(in[6], &label)){ DXSetError(ERROR_BAD_PARAMETER,"#10200","label"); goto error; } } /* if value list is integer create valuelist based on that integer * if list use that list * if NULL zerobased list */ if(in[4]){ if (!DXExtractInteger(in[4],&startlist)){ if (!DXGetArrayInfo((Array)in[4],&item2,NULL,NULL,NULL,NULL)) return ERROR; } else item2=0; } else{ item2=0; startlist=0; } /* read data (must be group or stringlist) */ if (in[3]){ /* if group call membernames to get stringlist */ strlist=membernames(in[3]); if (!strlist) return ERROR; if (!DXGetArrayInfo((Array)strlist,&item1,&type1,NULL,NULL,NULL)) goto error; if (type1!=TYPE_STRING){ DXSetError(ERROR_BAD_PARAMETER,"#10193","object"); goto error; } if (item2!=0 && item2!=item1) DXWarning("string list and value list not same length"); /* get valuelist */ if (item2==0){ vallist = zerobase(item1,startlist); if (!vallist) return ERROR; needfree = 1; } else vallist=in[4]; /* if cull is 0 fill in NULL strings with proper name * otherwise cull out NULL strings but keep indexing same */ if (icull==0){ newlist=fillnull(&strlist,in[3]); if (!newlist) goto error; DXDelete(strlist); strlist=newlist; } else{ if (!cullout(&strlist,&vallist)) return ERROR; needfree = 1; } #if !defined(SELECTOR_LIST_SUPPORT) if (in[1]) index=ismatch(strlist,cstring); if (item2!=0 && index > item2-1) index = 0; #else if (allowLists) { if (in[1]) { match_count=getmatches(strlist,in[1],&matched_indices); } else { match_count = 1; matched_indices = &index; } } else { if (in[1]) index=ismatch(strlist,cstring); if (item2!=0 && index > item2-1) index = 0; match_count = 1; matched_indices = &index; } #endif /* calculate the size of the UI message */ if ((i = getsize(strlist)) == 0) return ERROR; msglen += i; if ((i = getsize(vallist)) == 0){ DXSetError(ERROR_INVALID_DATA,"selector list is empty,unset cull"); goto error; } msglen += i; msglen += NAME_CHARS*4; msglen += NUMBER_CHARS; if (in[6]) msglen += (strlen(label) + 2); /* setup message */ ei.maxlen = msglen; ei.atend = 0; ei.msgbuf = (char *)DXAllocateZero(ei.maxlen+SLOP); if (!ei.msgbuf) goto error; ei.mp =ei.msgbuf; sprintf(ei.mp,"string list="); while(*ei.mp) ei.mp++; #if !defined(SELECTOR_LIST_SUPPORT) if (!dolist(strlist,out,1,&ei,index)) goto error; #else if (!dolist(strlist,out,1,&ei,matched_indices,match_count)) goto error; #endif sprintf(ei.mp," value list="); while(*ei.mp) ei.mp++; #if !defined(SELECTOR_LIST_SUPPORT) if (!dolist(vallist,out,0,&ei,index)) goto error; #else if (!dolist(vallist,out,0,&ei,matched_indices,match_count)) goto error; #endif #if !defined(SELECTOR_LIST_SUPPORT) sprintf(ei.mp," index=%d",index); while(*ei.mp) ei.mp++; #else sprintf(ei.mp," index="); while(*ei.mp) ei.mp++; if (match_count > 1) { sprintf(ei.mp,"{"); while(*ei.mp) ei.mp++; } for (i=0 ; i 1) { sprintf(ei.mp,"}"); while(*ei.mp) ei.mp++; } #endif DXDelete(strlist); if (needfree) DXDelete(vallist); strlist = NULL; vallist = NULL; } else { if (in[4]){ DXSetError(ERROR_INVALID_DATA, "valuelist is dependent on stringlist so stringlist must be specified"); return ERROR; } if (in[5]){ DXSetError(ERROR_INVALID_DATA, "cull is dependent on stringlist so stringlist must be specified"); return ERROR; } /* setup message default message */ msglen = 4*NAME_CHARS + 4*NUMBER_CHARS; if (in[6]) msglen += strlen(label) + 2; ei.maxlen = msglen; ei.atend = 0; ei.msgbuf = (char *)DXAllocateZero(ei.maxlen+SLOP); if (!ei.msgbuf) goto error; ei.mp =ei.msgbuf; if (in[1]){ out[0] = in[2]; out[1] = in[1]; } else{ /* make output */ i=1; out[0] = (Object)DXNewArray(TYPE_INT,CATEGORY_REAL,0); if (!DXAddArrayData((Array)out[0],0,1,&i)) goto error; out[1] = (Object)DXNewString("on"); sprintf(ei.mp,"string list=\"on\" "); while(*ei.mp) ei.mp++; sprintf(ei.mp,"value list= 1 "); while(*ei.mp) ei.mp++; sprintf(ei.mp,"index= 0"); while(*ei.mp) ei.mp++; } } /* print out label */ if (in[6]){ shape[0] = (int)strlen(label); sprintf(ei.mp, " label="); while(*ei.mp) ei.mp++; if (!_dxfprint_message(label, &ei,TYPE_STRING,1,shape,1)){ goto error; } } /* in DXMessage there is static buffer of MAX_MSGLEN so check length */ if (strlen(ei.msgbuf) > MAX_MSGLEN){ DXSetError(ERROR_INVALID_DATA,"#10920"); goto error; } DXUIMessage(id,ei.msgbuf); DXFree(ei.msgbuf); if (matched_indices && (matched_indices != &index)) DXFree(matched_indices); return OK; error: if (out[0]) out[0] = NULL; if (out[1]) out[1] = NULL; if (strlist) DXDelete((Object)strlist); if (vallist && needfree) DXDelete((Object)vallist); if (ei.msgbuf) DXFree(ei.msgbuf); if (matched_indices && (matched_indices != &index)) DXFree(matched_indices); return ERROR; } static Object membernames(Object o) { int i = 0,n=0,maxlen,size; char **cp = NULL, *string; Array a; float position; Class class=CLASS_GROUP; switch(DXGetObjectClass((Object)o)){ case CLASS_GROUP: class = DXGetGroupClass((Group)o); /* error if composite field */ if (class==CLASS_COMPOSITEFIELD){ DXSetError(ERROR_BAD_PARAMETER,"#10193","object"); return NULL; } if (!DXGetMemberCount((Group)o, &i)) return NULL; cp = (char **)DXAllocate(sizeof(char *) * (i+1)); if (!cp) return NULL; if (class==CLASS_SERIES){ for (i=0; DXGetSeriesMember((Series)o, i, &position); i++){ cp[i] = (char *)DXAllocate(MAXNAME); if (!cp[i]) goto error; sprintf(cp[i],"position=%g",position); } } else{ for (i=0; DXGetEnumeratedMember((Group)o, i, &string); i++){ if (string) { maxlen=strlen(string) + 1; cp[i] = (char *)DXAllocate(maxlen); if (!cp[i]) goto error; strcpy(cp[i],string); } else cp[i]=NULL; } } break; case CLASS_ARRAY: if (!DXGetArrayInfo((Array)o,&i,NULL,NULL,NULL,&size)) return NULL; cp = (char **)DXAllocate(sizeof(char *) * (i+1)); if (!cp) return NULL; for (i=0; DXExtractNthString((Object)o, i, &string); i++){ if (string) { cp[i] = (char *)DXAllocate(sizeof(char) * (size+1)); if (!cp[i]) goto error; strcpy(cp[i],string); } else cp[i]=NULL; } break; case CLASS_STRING: cp = (char **)DXAllocate(sizeof(char *)); if (!cp) return NULL; for (i=0; DXExtractNthString((Object)o, i, &string); i++){ if (string) { maxlen=strlen(string) +1; cp[i] = (char *)DXAllocate(maxlen); if (!cp[i]) goto error; strcpy(cp[i],string); } else cp[i]=NULL; } break; default: class = DXGetObjectClass((Object)o); DXSetError(ERROR_BAD_PARAMETER,"#10193","object"); return NULL; } if (i == 0) a = DXMakeStringList(1, " "); else a = DXMakeStringListV(i, cp); n=i; for (i=0; i= list_size) { if (list_size == 0) list_size = 8; else list_size *= 2; matches = DXReAllocate(matches,sizeof(int) * list_size); } matches[count] = i; count++; } } } } *matched_indices = matches; return count; } static int ismatch(Object list, char *cvalue) { int i,index=0; char *string; for (i=0; DXExtractNthString(list, i, &string); i++){ if (!strcmp(cvalue,string)){ index=i; break; } } return index; } #if !defined(SELECTOR_LIST_SUPPORT) static Error dolist(Object o,Object *out,int iout,struct einfo *ep, int index) #else static Error dolist(Object o,Object *out,int iout,struct einfo *ep, int *matched_indices, int matches) #endif { int j,i,item,rank,bytsize; int shape[MAXRANK]; Type type; Category cat; void *p, *outval; Pointer dp; #if defined(SELECTOR_LIST_SUPPORT) void *dest; #endif if (!DXGetArrayInfo((Array)o,&item,&type,&cat,&rank,shape)) return ERROR; bytsize = DXGetItemSize((Array)o); if (rank==0) shape[0]=1; p = DXGetArrayData((Array)o); if (item<1){ while(*ep->mp) ep->mp++; sprintf(ep->mp,"{}"); } else{ while(*ep->mp) ep->mp++; if (item==1) { sprintf(ep->mp,"{"); while(*ep->mp) ep->mp++; if (!_dxfprint_message(p,ep,type,rank,shape,item)) return ERROR; while(*ep->mp) ep->mp++; sprintf(ep->mp,"}"); } else if (!_dxfprint_message(p,ep,type,rank,shape,item)) return ERROR; } while(*ep->mp) ep->mp++; /* create output object for value */ #if !defined(SELECTOR_LIST_SUPPORT) outval = DXAllocate(bytsize); memcpy(outval,(void *)((byte *)p +bytsize*index),(size_t)bytsize); #else outval = DXAllocate(bytsize * matches); dest = outval; for (i=0 ; i