Logo Search packages:      
Sourcecode: condor version File versions  Download package

shared.cpp

/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you
 * may not use this file except in compliance with the License.  You may
 * obtain a copy of the License at
 * 
 *    http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ***************************************************************/


#include "classad/classad_distribution.h"
#include "classad/fnCall.h"
#include <time.h>

/***************************************************************************
 *
 * This is a sample shared library that shows how to write your own
 * user-defined functions within a shared library. By the way, it also
 * shows how to write user-defined functions that aren't in a shared
 * library. They are registered with FunctionCall::RegisterFunction() instead
 * of through the Init function that a shared library has.
 *
 ***************************************************************************/

using namespace std;
#ifdef WANT_CLASSAD_NAMESPACE
using namespace classad;
#endif

static bool todays_date(const char *name, const ArgumentList &arguments,
    EvalState &state, Value  &result);
static bool doublenum(const char *name, const ArgumentList &arguments,
    EvalState &state, Value  &result);

/***************************************************************************
 *
 * This is the table that maps function names to functions. This is desirable
 * because we don't want all possible functions in your library to be
 * callable from the ClassAd code, but only the ones you want to expose.
 * Also, you can name the functions anything you want. Note that you can
 * list a function twice--it can check to see what it was called when 
 * it was invoked (like a program's argv[0] and change it's behavior. 
 * This can be useful when you have functions that are nearly identical.
 * There are some examples in fnCall.C that do this, like sumAvg and minMax.
 *
 ***************************************************************************/
static ClassAdFunctionMapping functions[] = 
{
    { "todays_date", (void *) todays_date, 0 },
      { "double",      (void *) doublenum,   0 },
      { "triple",      (void *) doublenum,   0 },
    { "",            NULL,                 0 }
};

/***************************************************************************
 * 
 * Function: Init
 * Purpose:  This is the entry point for this library. It must be 
 *           declared extern "C". All it does is return a pointer to 
 *           the table of functions we declared above. It could also
 *           do some additional set up, should you wish. 
 *
 ***************************************************************************/
extern "C" 
{

      ClassAdFunctionMapping *Init(void)
      {
            return functions;
      }
}

/****************************************************************************
 *
 * Function: todays_date
 * Purpose:  This is a ClassAd function, and it is called during the
 *           evaluation of a ClassAd when a user uses the todays_date 
 *           function. (See the name mapping above, in the functions list.) 
 *           It returns a string that shows today's date.
 * Returns:  It returns true if the function can be evaluated successfully,
 *           and false otherwise.
 *
 ****************************************************************************/
static bool todays_date(
      const char         *, // name
      const ArgumentList &arguments,
      EvalState          &, // state
      Value              &result)
{
      bool    eval_successful;
      
      // We check to make sure that we are passed exactly zero arguments,
      if (arguments.size() != 0) {
            result.SetErrorValue();
            eval_successful = false;
      } else {
            time_t    current_seconds;
            struct tm *current_time;
            char      time_string[100];

            // Create the result we want. 
            current_seconds = time(NULL);
            current_time = localtime(&current_seconds);
            snprintf(time_string, 100, "%d-%02d-%02d", current_time->tm_year+1900,
                         current_time->tm_mon+1, current_time->tm_mday);

            // Copy the result into the "result" variable.
            result.SetStringValue(time_string);
            eval_successful = true;
      }

      return eval_successful;
}

/****************************************************************************
 *
 * Function: doublenum
 * Purpose:  This is a ClassAd function, and it is called during the
 *           evaluation of a ClassAd when a user uses the double function. 
 *           (See the name mapping above, in the functions list.) 
 *           It just doubles a number.
 * Returns:  It returns true if the function can be evaluated successfully,
 *           and false otherwise.
 *
 ****************************************************************************/
static bool doublenum(
      const char         *, // name
      const ArgumentList &arguments,
      EvalState          &state,
      Value              &result)
{
      Value arg;
      bool    eval_successful;
      
      // We check to make sure that we are passed exactly one argument,
      // then we have to evaluate that argument.
      if (arguments.size() != 1) {
            result.SetErrorValue();
            eval_successful = false;
      } else      if (!arguments[0]->Evaluate(state, arg)) {
            result.SetErrorValue();
            eval_successful = false;
      } else {
            // Here we check for the type of the argument and do
            // the appropriate thing. 
            // If it was undefined, we should "pass up" the undefined. 
            // If it was an error, or a type we can't deal with, it's an error
            // For numbers, we do the right thing, and we're careful
            // about using either integers or reals. 
            switch (arg.GetType()) {
            case Value::UNDEFINED_VALUE:
                  result.SetUndefinedValue( );
                  eval_successful = true;
                  break;

            case Value::ERROR_VALUE:
            case Value::CLASSAD_VALUE:
            case Value::LIST_VALUE:
            case Value::STRING_VALUE:
            case Value::ABSOLUTE_TIME_VALUE:
            case Value::RELATIVE_TIME_VALUE:
            case Value::BOOLEAN_VALUE:
                  result.SetErrorValue( );
                  eval_successful = true;
                  break;

            case Value::INTEGER_VALUE:
                  int int_value;

                  arg.IsIntegerValue(int_value);
                  result.SetIntegerValue(2 * int_value);
                  eval_successful = true;
                  break;

            case Value::REAL_VALUE:
                  double real_value;
                  arg.IsRealValue( real_value );
                  result.SetRealValue(2 * real_value);
                  eval_successful = true;
                  break;
            
            default:
                  eval_successful = false;
                  break;
            }
      }

      return eval_successful;
}

Generated by  Doxygen 1.6.0   Back to index