Initializing help system before first use

Other library functions and operators

The list of subroutines contains several groups of subroutines that may be applied to the new type task:

  • constructor functions (cloning and initialization with data)
  • subroutines for accessing detailed task information (getting and setting name, duration etc.)
  • assignment and comparison of tasks

Constructors

Being able to clone a type is required in certain cases of assignments (the use is similar to the cloning operation in C++):

static int task_clone(XPRMcontext ctx, void *libctx)
{
 s_task *task, *new_task;

 task=XPRM_POP_REF(ctx);
 if(task!=NULL)
 {
  new_task=task_create(ctx, libctx, NULL, 0);
  new_task->name=task->name;
  new_task->aflag=task->aflag;
  new_task->duedate=task->duedate;
  new_task->duration=task->duration;
  XPRM_PUSH_REF(ctx, new_task);
 }
 else
  XPRM_PUSH_REF(ctx, NULL);
 return XPRM_RT_OK;
}

As may be deduced from the test performed in this function, Mosel may pass the NULL pointer to a function in the place of an external type. This will typically happen if the object is an entry of a dynamic array that has not been initialized.

The following is an example of a constructor function. It creates a new task and fills it with the given data. This function enables the user to create a task by writing for example:

 task("a_task", 3.5, true, 10)

Several overloaded versions of this function are defined in our example. They are similar to this one and we omit printing them here. In every case, all given information needs to be taken from the stack and the reference to the new task is put back onto the stack.

static int task_new4(XPRMcontext ctx, void *libctx)
{
 s_task *task;

 task=task_create(ctx, libctx, NULL, 0);
 task->name=XPRM_POP_STRING(ctx);
 task->duration=XPRM_POP_REAL(ctx);
 task->aflag=XPRM_POP_INT(ctx);
 task->duedate=XPRM_POP_INT(ctx);
 XPRM_PUSH_REF(ctx, task);
 return XPRM_RT_OK;
}

Accessing detailed task information

We only give one example of a function for retrieving detailed task information (namely the task name), the other three are very similar:

static int task_getname(XPRMcontext ctx, void *libctx)
{
 s_task *task;

 task=XPRM_POP_REF(ctx);
 if(task==NULL)
 {
  mm->dispmsg(ctx, "Task: Accessing undefined task.\n");
  return XPRM_RT_ERROR;
 }
 XPRM_PUSH_STRING(ctx, task->name);
 return XPRM_RT_OK;
}

The following is an example of a function that sets some detailed task information (namely the duration):

static int task_setdur(XPRMcontext ctx, void *libctx)
{
 s_task *task;
 double dur;

 task=XPRM_POP_REF(ctx);
 dur=XPRM_POP_REAL(ctx);
 if(task==NULL)
 {
  mm->dispmsg(ctx, "Task: Accessing undefined task.\n");
  return XPRM_RT_ERROR;
 }
 task->duration=dur;
 return XPRM_RT_OK;
}

Since the names of the task access functions defined by our module adhere to the standard Mosel naming scheme (getproperty and setproperty) Mosel deduces automatically the dot notation for tasks. That means that for a task t we may use equivalently, for instance, getname(t) and t.name or setduration(t,10) and t.duration:=10.

Assignment and comparison operators

The assignment operation takes two task references from the stack, assigns the second to the first and deletes the second task since this is only an intermediate object:

static int task_assign(XPRMcontext ctx, void *libctx)
{
 s_task *task1, *task2;

 task1=XPRM_POP_REF(ctx);
 task2=XPRM_POP_REF(ctx);
 task1->name=task2->name;
 task1->aflag=task2->aflag;
 task1->duedate=task2->duedate;
 task1->duration=task2->duration;
 task_delete(ctx, libctx, task2, 0);
 return XPRM_RT_OK;
}

The implementation of the comparison operation for two tasks compares all the fields of the two structures, similarly to the implementation of the type comparison function that we have seen above in Section Type-related functions.

static int task_eql(XPRMcontext ctx, void *libctx)
{
 s_task *task1, *task2;
 int b;

 task1=XPRM_POP_REF(ctx);
 task2=XPRM_POP_REF(ctx);
 if(task1!=NULL)
 {
  if(task2!=NULL)
   b=((task1->name==task2->name) && (task1->duration==task2->duration)
     && (task1->aflag==task2->aflag) && (task1->duedate==task2->duedate));
  else
   b=0;
 }
 else
  b=(task2==NULL);
 XPRM_PUSH_INT(ctx,b);
 return XPRM_RT_OK;
}

Note that once we have defined the equality comparison, there is no need to implement the difference-between-tasks operation: it is derived by Mosel as being the negation of the equality.

© 2001-2020 Fair Isaac Corporation. All rights reserved. This documentation is the property of Fair Isaac Corporation (“FICO”). Receipt or possession of this documentation does not convey rights to disclose, reproduce, make derivative works, use, or allow others to use it except solely for internal evaluation purposes to determine whether to purchase a license to the software described in this documentation, or as otherwise set forth in a written software license agreement between you and FICO (or a FICO affiliate). Use of this documentation and the software described in it must conform strictly to the foregoing permitted uses, and no other use is permitted.