void
avtArrayDecomposeExpression::ProcessArguments(ArgsExpr *args, 
                                          ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();
    if (nargs != 2)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                        "this expression must be specified with exactly two "
                        "arguments.  Usage: array_decompose(array, #)");
    }

    // Tell the first argument to create its filters.
    ArgExpr *firstarg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstarg->GetExpr());
    firstTree->CreateFilters(state);

    ArgExpr *secondarg = (*arguments)[1];
    ExprParseTreeNode *secondTree = secondarg->GetExpr();
    std::string type = secondTree->GetTypeName();
    if (type == "IntegerConst")
        index = dynamic_cast<IntegerConstExpr*>(secondTree)->GetValue();
    else
    {
        debug5 << "avtArrayDecomposeExpression: Second argument is not an int."
               << endl;
        EXCEPTION2(ExpressionException, outputVariableName, "Second argument to array_decompose "
                                        "must be a number.");
    }
}
void
avtApplyEnumerationExpression::ProcessArguments(ArgsExpr *args,
                                        ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    if (arguments->size() != 2)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "the enumerate expression accepts only two arguments");
    }

    ArgExpr *listarg = (*arguments)[1];
    ExprParseTreeNode *listTree = listarg->GetExpr();
    if (listTree->GetTypeName() != "List")
    {
        debug1 << "avtApplyEnumerationExpression: second arg is not a list: "
               << listTree->GetTypeName() << endl;
        EXCEPTION2(ExpressionException, outputVariableName,
                   "the last argument to enumerate "
                   "must be a list");
    }

    ListExpr *list = dynamic_cast<ListExpr*>(listTree);
    std::vector<ListElemExpr*> *elems = list->GetElems();
    enumeratedValues.resize(elems->size());
    for (int i = 0 ; i < elems->size() ; i++)
    {
        if ((*elems)[i]->GetEnd())
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                       "the list for the enumerate "
                        "expression cannot contain ranges.");
        }

        ExprNode *item = (*elems)[i]->GetItem();
        if (item->GetTypeName() == "FloatConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            enumeratedValues[i] = dynamic_cast<FloatConstExpr*>(c)->GetValue();
        }
        else if (item->GetTypeName() == "IntegerConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            enumeratedValues[i] = dynamic_cast<IntegerConstExpr*>(c)->GetValue();
        }
        else 
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                       "the list for the enumerate "
                       "expression may contain only numbers.");
        }
    }

    // Let the base class do this processing.  We only had to over-ride this
    // function to determine the number of arguments.
    avtMultipleInputExpressionFilter::ProcessArguments(args, state);
}
void
avtApplyDataBinningExpression::ProcessArguments(ArgsExpr *args, 
                                        ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();
    if (nargs != 2)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "the syntax for the apply_data_binning "
                   "expression were incorrect.  Arguments should be: "
                   "<meshname>, \"databinning_name\"");
    }

    // Tell the first argument to create its filters.
    ArgExpr *firstarg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstarg->GetExpr());
    firstTree->CreateFilters(state);

    ArgExpr *secondarg = (*arguments)[1];
    ExprParseTreeNode *secondTree = secondarg->GetExpr();
    std::string type = secondTree->GetTypeName();
    if (type != "Var")
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "the syntax for the apply_data_binning "
                   "expression were incorrect.  Arguments should be: "
                   "<meshname>, \"databinning_name\"");
    }

    dbName = dynamic_cast<VarExpr*>(secondTree)->GetVar()->GetFullpath();
    if (getDataBinningCallback == NULL)
    {
        // No one ever registered the callback.  The NetworkManager should
        // do this.
        EXCEPTION2(ExpressionException, outputVariableName,
                   "An internal error occurred when "
                   "trying to locate the data binning.");
    }

    theDataBinning = getDataBinningCallback(getDataBinningCallbackArgs, dbName.c_str());
    if (theDataBinning == NULL)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "The data binning name you have specified is not "
                   "recognized.  VisIt is only aware of the data binning that"
                   " have been calculated this session.  In addition, if "
                   "the engine crashes, you must have VisIt regenerate "
                   "the data binnings again.");
    }
}
void
avtArraySumExpression::ProcessArguments(ArgsExpr *args, 
                                          ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();
    if (nargs != 1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                        "this expression must be specified with exactly one "
                        "arguments.  Usage: array_sum(array)");
    }

    // Tell the first argument to create its filters.
    ArgExpr *firstarg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstarg->GetExpr());
    firstTree->CreateFilters(state);
}
void
avtTimeIteratorExpression::ProcessArguments(ArgsExpr *args,
                                            ExprPipelineState *state)
{
    int  i;

    // get the argument list and # of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();

    // check for call with no args
    if (nargs < NumberOfVariables())
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "Not enough arguments to time iterator expression");
    }

    // Each of these arguments should be variables.
    for (i = 0 ; i < NumberOfVariables() ; i++)
    {
        ArgExpr *arg = (*arguments)[i];
        avtExprNode *tree = dynamic_cast<avtExprNode*>(arg->GetExpr());
        tree->CreateFilters(state);
    }

    std::vector<int> timecontrols;
    for (i = NumberOfVariables() ; i < nargs ; i++)
    {
        ArgExpr *arg= (*arguments)[i];
        ExprParseTreeNode *tree= arg->GetExpr();
        std::string argtype = tree->GetTypeName();
        // check for arg passed as integer
        if (argtype == "IntegerConst")
        {
            int t = dynamic_cast<IntegerConstExpr*>(tree)->GetValue();
            timecontrols.push_back(t);
        }
        else if (argtype == "StringConst")
        {
            std::string s = dynamic_cast<StringConstExpr*>(tree)->GetValue();
            if (s == "pos_cmfe")
            {
                if (i == nargs-1)
                {
                    EXCEPTION2(ExpressionException, outputVariableName,
                               "If specify pos_cmfe, then you must follow that"
                               " immediately with a default variable.");
                }
                i++;
                ArgExpr *arg = (*arguments)[i];
                avtExprNode *tree = dynamic_cast<avtExprNode*>(arg->GetExpr());
                tree->CreateFilters(state);
                cmfeType = POS_CMFE;
            }
            else if (s != "conn_cmfe")
            {
                char msg[1024];
                SNPRINTF(msg, 1024, "Could not understand meaning of \"%s\"",
                                    s.c_str());
                EXCEPTION2(ExpressionException, outputVariableName,msg);
            }
        }
    }
    if (timecontrols.size() == 3)
    {
        firstTimeSlice = timecontrols[0];
        lastTimeSlice  = timecontrols[1];
        timeStride     = timecontrols[2];
    }
    else if (timecontrols.size() != 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "The specification of time must use integers.  "
                   "These integers are dump indices, 0-indexed."
                   "If you specify time controls, there must be three integers"
                   ", start, stop, stride");
    }
}
// ****************************************************************************
//  Method: avtRecenterExpression::ProcessArguments
//
//  Purpose:
//      Parses optional centering argument.
//
//  Arguments:
//      args      Expression arguments
//      state     Expression pipeline state
//
//  Programmer:   Sean Ahern
//  Creation:     Wed Sep 10 12:04:12 EDT 2008
//
// ****************************************************************************
void
avtRecenterExpression::ProcessArguments(ArgsExpr *args,
                                        ExprPipelineState *state)
{
    // Get the argument list and number of arguments.
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();

    // Check for a call with no arguments.
    if (nargs == 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName,
                   "recenter(): Incorrect syntax.\n"
                   " usage: recenter(varname, [centering])\n"
                   " The centering parameter is optional "
                   " and specifies nodal or zonal centering.\n"
                   " Valid values of centering: \"nodal\", \"zonal\", and \"toggle\".\n"
                   " The default centering is to toggle, that is, to convert "
                   " nodal to zonal or zonal to nodal.");
    }

    // Grab off the first argument.
    ArgExpr *firstArg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstArg->GetExpr());
    firstTree->CreateFilters(state);

    // Check if we have a second optional argument that tells us how to
    // center.
    //
    // Options:
    //  nodal:  Recenter to nodes
    //  zonal:  Recenter to zones
    //  toggle: Toggle centering
    // Default: toggle

    if (nargs > 1)
    {
        ArgExpr *secondArg = (*arguments)[1];
        ExprParseTreeNode *secondTree = secondArg->GetExpr();
        std::string secondType = secondTree->GetTypeName();

        // Check for argument passed as string
        if (secondType == "StringConst")
        {
            std::string sval = dynamic_cast<StringConstExpr*>(secondTree)->GetValue();

            if (sval == "toggle")
                recenterMode = Toggle;
            else if (sval == "nodal")
                recenterMode = Nodal;
            else if (sval == "zonal")
                recenterMode = Zonal;
            else
            {
                EXCEPTION2(ExpressionException, outputVariableName,
                           "avtRecenterExpression: Invalid second argument.\n"
                           " Valid options are: \"nodal\", \"zonal\", or \"toggle\".");
            }
        }
        else    // Invalid argument type
        {
            EXCEPTION2(ExpressionException, outputVariableName,
                       "avtRecenterExpression: Invalid second argument type.\n"
                       "Must be a string with one of: \"nodal\", \"zonal\", \"toggle\".");
        }
    }
}
void
avtArrayComposeWithBinsExpression::ProcessArguments(ArgsExpr *args,
                                        ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    nvars = (int)arguments->size()-1;

    int idx_of_list = arguments->size()-1;
    ArgExpr *listarg = (*arguments)[idx_of_list];
    ExprParseTreeNode *listTree = listarg->GetExpr();
    if (listTree->GetTypeName() != "List")
    {
        debug1 << "avtArrayComposeWithBinsExpression: second arg is not a "
               << "list: " << listTree->GetTypeName() << endl;
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "the last argument to array_compose_"
                   "with_bins must be a list");
    }

    ListExpr *list = dynamic_cast<ListExpr*>(listTree);
    std::vector<ListElemExpr*> *elems = list->GetElems();
    binRanges.resize(elems->size());
    if ((int)elems->size() != nvars+1)
    {
        EXCEPTION2(ExpressionException, outputVariableName, 
                   "the list for array_compose_with_bins"
                   " must have one more number than there are variables. "
                   " For two variables (V1 and V2), there should be a list of"
                   " size 3: [L0, L1, L2].  V1's bin goes from L0 to L1, "
                   "and V2's bin goes from L1 to L2.");
    }
    for (size_t i = 0 ; i < elems->size() ; i++)
    {
        if ((*elems)[i]->GetEnd())
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "the list for array_compose_with"
                       "_bins expression cannot contain ranges.");
        }

        ExprNode *item = (*elems)[i]->GetItem();
        if (item->GetTypeName() == "FloatConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            binRanges[i] = dynamic_cast<FloatConstExpr*>(c)->GetValue();
        }
        else if (item->GetTypeName() == "IntegerConst")
        {
            ConstExpr *c = dynamic_cast<ConstExpr*>(item);
            binRanges[i] = dynamic_cast<IntegerConstExpr*>(c)->GetValue();
        }
        else 
        {
            EXCEPTION2(ExpressionException, outputVariableName, 
                       "the list for the array_compose"
                       "_with_bins expression may contain only numbers.");
        }
    }

    // Let the base class do this processing.  We only had to over-ride this
    // function to determine the number of arguments.
    avtMultipleInputExpressionFilter::ProcessArguments(args, state);
}
// ****************************************************************************
//  Method: avtMatvfExpression::ProcessArguments
//
//  Purpose:
//      Tells the first argument to go generate itself.  Parses the second
//      argument into a list of material names.
//
//  Arguments:
//      inDS      The input dataset.
//
//  Returns:      The derived variable.  The calling class must free this
//                memory.
//
//  Programmer:   Sean Ahern
//  Creation:     Tue Mar 18 23:20:06 America/Los_Angeles 2003
//
//  Modifications:
//    Jeremy Meredith, Mon Sep 29 12:13:04 PDT 2003
//    Added support for integer material indices.
//    Added support for integer ranges.
//
//    Hank Childs, Thu Jul 15 14:44:17 PDT 2004
//    Make sure the base pointer type for the dynamic cast is in the 
//    inheritance tree of what we are downcasting type. ('5201)
//
//    Jeremy Meredith, Wed Nov 24 12:26:21 PST 2004
//    Renamed EngineExprNode to avtExprNode due to a refactoring.
//    Also renamed Token to ExprToken for the same reason.
//    Changed the base type for an Arg's expression.
//
//    Jeremy Meredith, Mon Jun 13 11:42:38 PDT 2005
//    Changed the way constant expressions work.
//
// ****************************************************************************
void
avtMatvfExpression::ProcessArguments(ArgsExpr *args, ExprPipelineState *state)
{
    // Check the number of arguments
    std::vector<ArgExpr*> *arguments = args->GetArgs();
    int nargs = arguments->size();
    if (nargs == 0)
    {
        EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression: No arguments given.");
    }
    // Tell the first argument to create its filters.
    ArgExpr *firstarg = (*arguments)[0];
    avtExprNode *firstTree = dynamic_cast<avtExprNode*>(firstarg->GetExpr());
    firstTree->CreateFilters(state);

    // Check if there's a second argument.
    if (nargs == 1)
    {
        debug5 << "avtMatvfExpression: No second argument." << endl;
        return;
    }

    // See if there are other arguments.
    if (nargs > 2)
    {
        EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression only expects two "
                   "arguments.  To specify more than one material, use a "
                   "list (e.g. [1,4,5:9].");
    }

    // Pull off the second argument and see if it's a string or a list.
    ArgExpr *secondarg = (*arguments)[1];
    ExprParseTreeNode *secondTree = secondarg->GetExpr();
    std::string type = secondTree->GetTypeName();
    if ((type != "IntegerConst") && (type != "StringConst") && (type != "List"))
    {
        debug5 << "avtMatvfExpression: Second argument is not a constant or a list: " << type.c_str() << endl;
        EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression: Second argument is not a constant or a list.");
    }

    if (type == "IntegerConst" || type == "StringConst")
    {
        // It's a single constant.
        AddMaterial(dynamic_cast<ConstExpr*>(secondTree));
    }
    else
    {
        // It's a list.  Process all of them.
        ListExpr *list = dynamic_cast<ListExpr*>(secondTree);
        std::vector<ListElemExpr*> *elems = list->GetElems();
        for(int i=0;i<elems->size();i++)
        {
            if ((*elems)[i]->GetEnd())
            {
                // it's a range
                ExprNode *begExpr  = (*elems)[i]->GetBeg();
                ExprNode *endExpr  = (*elems)[i]->GetEnd();
                ExprNode *skipExpr = (*elems)[i]->GetSkip();
                
                if (begExpr->GetTypeName() != "IntegerConst" ||
                    endExpr->GetTypeName() != "IntegerConst" ||
                    (skipExpr && skipExpr->GetTypeName() != "IntegerConst"))
                {
                    EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression: "
                               "Range must contain integers.");
                }

                int beg  = dynamic_cast<IntegerConstExpr*>(begExpr)->GetValue();
                int end  = dynamic_cast<IntegerConstExpr*>(endExpr)->GetValue();
                int skip = !skipExpr ? 1 : 
                           dynamic_cast<IntegerConstExpr*>(skipExpr)->GetValue();

                if (skip <= 0 || beg > end)
                {
                    EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression: "
                               "Range must be of the form beg:end[:skip].");
                }

                for (int m = beg; m <= end ; m += skip)
                    matIndices.push_back(m);
            }
            else
            {
                ExprNode *item = (*elems)[i]->GetItem();
                std::string type = item->GetTypeName();
                if (type != "IntegerConst" && type != "StringConst")
                {
                    debug5 << "avtMatvfExpression: List element is not an "
                              "integer constant, a string constant, "
                              "or a list: " << type.c_str() << endl;
                    EXCEPTION2(ExpressionException, outputVariableName, "avtMatvfExpression: "
                               "List element is not an int/string constant "
                               "or a list.");
                }

                AddMaterial(dynamic_cast<ConstExpr*>(item));
            }
        }
    }
}