"Fossies" - the Fresh Open Source Software archive

Member "dx-4.4.4/src/exec/dxmods/append.c" of archive dx-4.4.4.tar.gz:


/***********************************************************************/
/* 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 <dxconfig.h>


#include <string.h>
#include <dx/dx.h>
#include "_construct.h"
#include "list.h"

#define MAXOBJECTS 43    /* must match mdf-c generated dx.mdf file */

/* extern, but as far as i know not being used anywhere else */
Group _dxfBuildGroup(Object *in);


int
m_Append(Object *in, Object *out)
{
/* was going to have append accept same inputs as List, but
 * the rest of the inputs are (name,object) pairs, or (value,object)
 * pairs.  that doesn't make sense for list, which is just a 
 * simple list of objects.
 */
#if 0
    Class c;

    if (in[0]) {
	
	c = DXGetObjectClass(in[0]);

	if (c == CLASS_GROUP)
	    out[0] = (Object)_dxfBuildGroup(in);
	
	else if (c == CLASS_ARRAY  ||  c == CLASS_STRING)
	    out[0] = (Object)_dxfBuildList(in);

    } else {

	/* shouldn't this depend on whether the first thing
         * is an array or not?  guess i can't change the existing
	 * default which is to make a new empty group and add the
	 * rest of the inputs as members.
	 */
#endif

	out[0] = (Object)_dxfBuildGroup(in);
#if 0
    }
#endif
    
    return (out[0] != NULL) ? OK : ERROR;
}


Group _dxfBuildGroup(Object *in)
{
    int i;
    int seen_null = 0;
    int say_warn = 0;
    int seen_valid = 0;
    Class gclass = (Class) 0;
    Object newo;
    Group newgroup = NULL;
    char *cp;
    float f;
    int cnt;

    /* this will now do two distinct functions:  
     *  if the first input is a group, it makes all subsequent
     *  inputs a member of the group.  
     *  if the first input is an array or string, it concatinates
     *  all subsequent inputs to the end of the array.
     */

    if (in[0]) {
	
	if (DXGetObjectClass(in[0]) != CLASS_GROUP) {
	    DXSetError(ERROR_BAD_CLASS, "#10192", "input");
	    goto error;
	}
	gclass = DXGetGroupClass((Group)in[0]);
	newgroup = (Group)DXCopy(in[0], COPY_STRUCTURE);
	
    } else {
	newgroup = DXNewGroup();
	if (!newgroup)
	    goto error;

	/* DXWarning("#4018");  -* creating a new group */
    }
    
    /* for each pair of inputs, if they are both null, skip them and
     *  continue.  if one is non-null, return an error.  if both are
     *  good, add them to the group.  look for repeated names.
     */
    for (i = 1; i<MAXOBJECTS; i += 2) {

        /* skip null pairs */
        if (!in[i] && !in[i+1]) {
            seen_null = 1;
            continue;
        }

	if (!seen_valid)
	    seen_valid = 1;

        /* check for mismatched pairs of object/names.
         *  make it ok to have an object and no name, but require an
         *  object if there is a name.  for a series, still require
	 *  the series parm.
         */
        if ((gclass == CLASS_SERIES) && in[i] && !in[i+1]) {
            DXSetError(ERROR_BAD_PARAMETER, "#11070", i/2);
            goto error;
        }

        if (!in[i] && in[i+1]) {
            DXSetError(ERROR_BAD_PARAMETER, "#11065", i/2);
            goto error;
        }

        /* warn if you see valid pairs after null pairs, but it's not
         *  an error.
         */
        if (seen_null) {
            say_warn = 1;
            seen_null = 0;
        }

	    
	switch (gclass) {

	  case CLASS_SERIES:
	    if (!DXExtractFloat(in[i+1], &f)) {
		DXSetError(ERROR_BAD_PARAMETER, "#11070", i/2);
		goto error;
	    }
	    
	    /* this has to be a copy because DXSetSeriesMember adds a series
	     *  position attribute, so series members can't be shared between
	     *  series groups if they have different positions.
	     */
	    if (!(newo = DXCopy(in[i], COPY_STRUCTURE)))
		goto error;
	    
	    /* if it didn't copy and it's an array, try harder to copy it */
	    if ((newo == in[i]) && (DXGetObjectClass(in[i]) == CLASS_ARRAY))
		newo = (Object)_dxfReallyCopyArray((Array)in[i]);
	    
	    if (!DXGetMemberCount(newgroup, &cnt))
		goto error;
	    
	    if (!DXSetSeriesMember((Series)newgroup, cnt, f, newo))
		goto error;
	    
	    break;
	    
	  default:
	    if (!in[i+1])
		cp = NULL;
	    else {
		if (!DXExtractString(in[i+1], &cp)) {
		    DXSetError(ERROR_BAD_PARAMETER, "#11080", i/2);
		    goto error;
		}
	    }
	    
	    if (cp && DXGetMember(newgroup, cp) != NULL) {
		DXSetError(ERROR_BAD_PARAMETER, "#11085", i/2, cp);
		goto error;
	    }

	    if (!DXSetMember(newgroup, cp, in[i]))
		goto error;
	    
	    break;
	}

    }
    
    if (!seen_valid)
	; /* DXWarning("#4016");  -* no inputs specified; nothing appended */
    
    if (say_warn)
        ; /* DXWarning("#4010");  -* valid object following NULL in list */

    return newgroup;

  error:
    DXDelete((Object)newgroup);
    return NULL;
}