/***********************************************************************/ /* 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" */ /***********************************************************************/ /* * $Header: /home/gda/dxcvs/dx/src/exec/dxmods/echo.c,v 1.3 1999/05/10 15:45:24 gda Exp $ */ #include #include #include #include #include #define MAXPARMS 21 #define MSGLEN 1024 /* can this be bigger and not blow up the UI? */ #define SLOP 128 #define AtEnd(p) ((p)->atend) #define MIN(a, b) (aatend) return 1; if ((ep->mp - ep->msgbuf) >= ep->maxlen) { ep->atend = 1; sprintf(ep->mp, " "); while(*ep->mp) ep->mp++; return 1; } return 0; } /* NOTE: If you change the definition, also change the usage in * dxloutputvalue.m */ Error _dxf_ConvertObjectsToStringValues(Object *in, int nobj, char **retstr); static char *ClassNameString(Class c); static void pv(struct einfo *ep, Type t, Pointer value, int offset); static void pc(struct einfo *ep, Type t, Pointer value, int offset); static void pq(struct einfo *ep, Type t, Pointer value, int offset); static void pa(struct einfo *ep, Category c, Type t, Pointer value, int offset); static void pvalue(struct einfo *ep, Type type, Category category, int rank, int *shape, Pointer value); static void pvlist(struct einfo *ep, int nitems, Type type, Category category, int rank, int *shape, Pointer value, int itemsize); static void ps(struct einfo *ep, char *); int m_Echo(Object *in, Object *out) { int input, incount; char *echo_string = NULL; /* ok, until we get an arg count from the exec, we can count up * the parms ourselves. print until the last non-null one. */ for (input = 0, incount = -1; input < MAXPARMS; input++) if(in[input]) incount = input+1; /* the default message used to be an empty string - now it just * returns WITHOUT printing if input is null. */ if (incount <= 0) return OK; if (!_dxf_ConvertObjectsToStringValues(in,incount,&echo_string)) goto error; /* prevent messages from being mangled if they start with # */ if (echo_string[0] == '#') DXExpandMessage(0); DXUIMessage("ECHO", echo_string); if (echo_string[0] == '#') DXExpandMessage(1); if (echo_string) DXFree((Pointer)echo_string); return OK; error: if (echo_string) DXFree((Pointer)echo_string); return ERROR; } static char * ClassNameString(Class c) { switch(c) { case CLASS_MIN: return "Min object "; case CLASS_OBJECT: return "Generic Object "; case CLASS_PRIVATE: return "Private object "; case CLASS_STRING: return "String object "; case CLASS_FIELD: return "Field object "; case CLASS_GROUP: return "Group object "; case CLASS_SERIES: return "Series object "; case CLASS_COMPOSITEFIELD: return "Compositefield object "; case CLASS_MULTIGRID: return "Multigrid object "; case CLASS_ARRAY: return "Array object "; case CLASS_REGULARARRAY: return "Regulararray object "; case CLASS_PATHARRAY: return "Patharray object "; case CLASS_PRODUCTARRAY: return "Productarray object "; case CLASS_MESHARRAY: return "Mesharray object "; case CLASS_XFORM: return "Xform object "; case CLASS_SCREEN: return "Screen object "; case CLASS_CLIPPED: return "Clipped object "; case CLASS_CAMERA: return "Camera object "; case CLASS_LIGHT: return "Light object "; case CLASS_MAX: return "Max object "; case CLASS_DELETED: return "Deleted object "; case CLASS_CONSTANTARRAY: return "Constantarray object "; default: return "Unknown object "; } /* notreached */ } static void pv(struct einfo *ep, Type t, Pointer value, int offset) { switch(t) { case TYPE_STRING: if (((char *)value)[offset] == '%') *ep->mp = '%'; ep->mp++; sprintf(ep->mp, "%c", ((char *)value)[offset]); break; case TYPE_SHORT: sprintf(ep->mp, "%d", ((short *)value)[offset]); break; case TYPE_INT: sprintf(ep->mp, "%d", ((int *)value)[offset]); break; case TYPE_FLOAT: sprintf(ep->mp, "%g", ((float *)value)[offset]); break; case TYPE_DOUBLE: sprintf(ep->mp, "%g", ((double *)value)[offset]); break; case TYPE_UINT: sprintf(ep->mp, "%u", ((uint *)value)[offset]); break; case TYPE_USHORT: sprintf(ep->mp, "%u", ((ushort *)value)[offset]); break; case TYPE_UBYTE: sprintf(ep->mp, "%u", ((ubyte *)value)[offset]); break; case TYPE_BYTE: sprintf(ep->mp, "%d", ((byte *)value)[offset]); break; case TYPE_HYPER: default: *ep->mp = '?'; ep->mp++; break; } while(*ep->mp) ep->mp++; EndCheck(ep); } static void pc(struct einfo *ep, Type t, Pointer value, int offset) { if(EndCheck(ep)) return; sprintf(ep->mp, "("); while(*ep->mp) ep->mp++; pv(ep, t, value, offset); if (EndCheck(ep)) return; sprintf(ep->mp, ", "); while(*ep->mp) ep->mp++; pv(ep, t, value, offset+1); if (EndCheck(ep)) return; sprintf(ep->mp, ")"); while(*ep->mp) ep->mp++; } static void pq(struct einfo *ep, Type t, Pointer value, int offset) { if (EndCheck(ep)) return; sprintf(ep->mp, "("); while(*ep->mp) ep->mp++; pv(ep, t, value, offset); if (EndCheck(ep)) return; sprintf(ep->mp, ", "); while(*ep->mp) ep->mp++; pv(ep, t, value, offset+1); if (EndCheck(ep)) return; sprintf(ep->mp, ", "); while(*ep->mp) ep->mp++; pv(ep, t, value, offset+2); if (EndCheck(ep)) return; sprintf(ep->mp, ", "); while(*ep->mp) ep->mp++; pv(ep, t, value, offset+3); if (EndCheck(ep)) return; sprintf(ep->mp, ")"); while(*ep->mp) ep->mp++; } static void pa(struct einfo *ep, Category c, Type t, Pointer value, int offset) { offset *= DXCategorySize(c); switch (c) { case CATEGORY_REAL: pv(ep, t, value, offset); if (EndCheck(ep)) return; break; case CATEGORY_COMPLEX: pc(ep, t, value, offset); if (EndCheck(ep)) return; break; case CATEGORY_QUATERNION: pq(ep, t, value, offset); if (EndCheck(ep)) return; break; } } static void pvalue(struct einfo *ep, Type type, Category category, int rank, int *shape, Pointer value) { int i, j, k; switch(rank) { case 0: pa(ep, category, type, value, 0); if (EndCheck(ep)) return; sprintf(ep->mp, " "); while(*ep->mp) ep->mp++; break; case 1: if (EndCheck(ep)) return; if (type == TYPE_STRING) ps(ep, (char *)value); else { sprintf(ep->mp, "["); while(*ep->mp) ep->mp++; for(i=0; imp, " "); while(*ep->mp) ep->mp++; } if (EndCheck(ep)) return; sprintf(ep->mp, "] "); while(*ep->mp) ep->mp++; } break; case 2: if (EndCheck(ep)) return; sprintf(ep->mp, "["); while(*ep->mp) ep->mp++; for(i=0; imp++ = ' '; } else { sprintf(ep->mp, "["); while(*ep->mp) ep->mp++; for(j=0; jmp, " "); while(*ep->mp) ep->mp++; } if (EndCheck(ep)) return; sprintf(ep->mp, "]"); while(*ep->mp) ep->mp++; } } if (EndCheck(ep)) return; sprintf(ep->mp, "]"); while(*ep->mp) ep->mp++; break; case 3: if (EndCheck(ep)) return; sprintf(ep->mp, "["); while(*ep->mp) ep->mp++; for(i=0; imp, "["); while(*ep->mp) ep->mp++; for(j=0; jmp++ = ' '; } else { sprintf(ep->mp, "["); while(*ep->mp) ep->mp++; for(k=0; kmp, " "); while(*ep->mp) ep->mp++; } if (EndCheck(ep)) return; sprintf(ep->mp, "]"); while(*ep->mp) ep->mp++; } } if (EndCheck(ep)) return; sprintf(ep->mp, "]"); while(*ep->mp) ep->mp++; } if (EndCheck(ep)) return; sprintf(ep->mp, "]"); while(*ep->mp) ep->mp++; break; default: sprintf(ep->mp, "is rank %d ", rank); while(*ep->mp) ep->mp++; break; } EndCheck(ep); } static void pvlist(struct einfo *ep, int nitems, Type type, Category category, int rank, int *shape, Pointer value, int itemsize) { int i; if (EndCheck(ep)) return; sprintf(ep->mp, "{ "); while(*ep->mp) ep->mp++; for (i=0; imp++ = ' '; } if (EndCheck(ep)) return; sprintf(ep->mp, " }"); while(*ep->mp) ep->mp++; } static void ps(struct einfo *ep, char *cp) { while(*cp) { if(*cp == '%') *ep->mp++ = '%'; *ep->mp++ = *cp++; if (EndCheck(ep)) return; } } Error _dxf_ConvertObjectsToStringValues(Object *in, int nobj, char **retstr) { struct einfo ei; int input, items, i, rank, shape[100]; char *cp; Pointer dp; Class class; Type t; Category c; /* allocate a buffer in which to collect the message. */ ei.maxlen = MSGLEN; ei.atend = 0; ei.msgbuf = (char *)DXAllocateZero(MSGLEN+SLOP); if (!ei.msgbuf) goto error; /* loop through input, adding to the end of the accumulated string * each time. since we used DXAllocateZero, the first time through * the loop, *mp will be null and won't be advanced. */ ei.mp = ei.msgbuf; for (input=0; input < nobj && !AtEnd(&ei); input++) { /* check for null parms */ if(!in[input]) { sprintf(ei.mp, "NULL"); while(*ei.mp) ei.mp++; } else switch ((class = DXGetObjectClass(in[input]))) { case CLASS_ARRAY: if (!DXGetArrayInfo((Array)in[input], &items, &t, &c, &rank, shape)) goto error; dp = DXGetArrayData((Array)in[input]); if (!dp) goto error; if (items == 1) pvalue(&ei, t, c, rank, shape, dp); else pvlist(&ei, items, t, c, rank, shape, dp, DXGetItemSize((Array)in[input])); break; case CLASS_STRING: cp = DXGetString((String)(in[input])); ps(&ei, cp); break; case CLASS_GROUP: class = DXGetGroupClass((Group)in[input]); /* fall thru! */ default: sprintf(ei.mp, "%s", ClassNameString(class)); while(*ei.mp) ei.mp++; break; } if (input < (nobj-1)) *ei.mp++ = ' '; } *retstr = ei.msgbuf; return OK; error: if (ei.msgbuf) DXFree((Pointer)ei.msgbuf); *retstr = NULL; return ERROR; }