| |||||||||||
Definition of type 'task' and subroutines for accessing it Description Language extensions provided by this module:
Source Files By clicking on a file name, a preview is opened at the bottom of this page.
Data Files task.c /****************************************** Mosel NI Examples ================= File task.c ``````````` Example module defining a new type task regrouping information related to tasks in scheduling problems. (Short example for User Guide: only rudimentary memory management) (c) 2008 Fair Isaac Corporation author: S. Heipcke, 2002 *******************************************/ #include <stdlib.h> #include <stdio.h> #include <string.h> #include "xprm_ni.h" #ifdef _WIN32 #define alloca(a) _alloca(a) #define snprintf _snprintf #else #include <alloca.h> #endif #define TASK_MAXNAME 128 #define TASK_MAXTIME 100 #define TASK_MEM 20 #define TASK_NUMPARAM 2 /**** Function prototypes ****/ DSO_INIT task_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf); static int task_getpar(XPRMcontext ctx,void *libctx); static int task_setpar(XPRMcontext ctx,void *libctx); static int task_getname(XPRMcontext ctx,void *libctx); static int task_getdur(XPRMcontext ctx,void *libctx); static int task_getaflag(XPRMcontext ctx,void *libctx); static int task_getdue(XPRMcontext ctx,void *libctx); static int task_setname(XPRMcontext ctx,void *libctx); static int task_setdur(XPRMcontext ctx,void *libctx); static int task_setaflag(XPRMcontext ctx,void *libctx); static int task_setdue(XPRMcontext ctx,void *libctx); static int task_clone(XPRMcontext ctx,void *libctx); static int task_new1(XPRMcontext ctx,void *libctx); static int task_new2(XPRMcontext ctx,void *libctx); static int task_new3(XPRMcontext ctx,void *libctx); static int task_new4(XPRMcontext ctx,void *libctx); static int task_new5(XPRMcontext ctx,void *libctx); static int task_assign(XPRMcontext ctx,void *libctx); static int task_eql(XPRMcontext ctx,void *libctx); static void *task_create(XPRMcontext ctx,void *libctx,void *,int); static void task_delete(XPRMcontext ctx,void *libctx,void *todel,int); static int task_tostr(XPRMcontext ctx,void *libctx,void *toprt,char *str, int len,int typnum); static int task_fromstr(XPRMcontext ctx,void *libctx,void *toinit, const char *str,int typnum, const char **endp); static int task_copy(XPRMcontext ctx,void *libctx,void *toinit,void *src,int typnum); static int task_findparam(const char *name,int *type); static void *task_nextparam(void *ref,const char **name,const char **desc, int *type); static void *task_reset(XPRMcontext ctx,void *libctx,int version); /**** Structures for passing info to Mosel ****/ /* Constants */ static XPRMdsoconst tabconst[]= { XPRM_CST_BOOL("TASK_FLAG",1), /* Constant with value true */ XPRM_CST_BOOL("TASK_NOFLAG",0) /* Constant with value false */ }; /* Subroutines */ static XPRMdsofct tabfct[]= { /* Implementing Mosel subroutines get/setparam for this module: */ {"",XPRM_FCT_GETPAR,XPRM_TYP_NOT,0,NULL,task_getpar}, {"",XPRM_FCT_SETPAR,XPRM_TYP_NOT,0,NULL,task_setpar}, /* Accessing task info: */ {"getname",1000,XPRM_TYP_STRING,1,"|task|",task_getname}, {"getduration",1002,XPRM_TYP_REAL,1,"|task|",task_getdur}, {"getaflag",1003,XPRM_TYP_BOOL,1,"|task|",task_getaflag}, {"getduedate",1004,XPRM_TYP_INT,1,"|task|",task_getdue}, {"setname",1005,XPRM_TYP_NOT,2,"|task|s",task_setname}, {"setduration",1006,XPRM_TYP_NOT,2,"|task|r",task_setdur}, {"setaflag",1007,XPRM_TYP_NOT,2,"|task|b",task_setaflag}, {"setduedate",1008,XPRM_TYP_NOT,2,"|task|i",task_setdue}, /* Constructors for tasks: */ {"@&",1011,XPRM_TYP_EXTN,1,"task:|task|",task_clone}, {"@&",1012,XPRM_TYP_EXTN,1,"task:s",task_new1}, {"@&",1013,XPRM_TYP_EXTN,1,"task:r",task_new2}, {"@&",1014,XPRM_TYP_EXTN,2,"task:sr",task_new3}, {"@&",1015,XPRM_TYP_EXTN,4,"task:srbi",task_new4}, {"@&",1016,XPRM_TYP_EXTN,3,"task:rbi",task_new5}, /* Operators for assignment and comparison: */ {"@:",1020,XPRM_TYP_NOT,2,"|task||task|",task_assign}, {"@=",1021,XPRM_TYP_BOOL,2,"|task||task|",task_eql} }; /* Types */ static XPRMdsotyp tabtyp[]= { {"task",1,XPRM_DTYP_PNCTX|XPRM_DTYP_RFCNT,task_create,task_delete,task_tostr,task_fromstr,task_copy} }; /* Services */ static XPRMdsoserv tabserv[]= { {XPRM_SRV_PARAM,(void *)task_findparam}, /* Req. by parameters*/ {XPRM_SRV_PARLST,(void *)task_nextparam}, /* Opt. with parameters*/ {XPRM_SRV_RESET,(void *)task_reset} /* Req. by types */ }; /* Interface structure */ static XPRMdsointer dsointer= { sizeof(tabconst)/sizeof(XPRMdsoconst),tabconst, sizeof(tabfct)/sizeof(XPRMdsofct),tabfct, sizeof(tabtyp)/sizeof(XPRMdsotyp),tabtyp, sizeof(tabserv)/sizeof(XPRMdsoserv),tabserv }; /**** Structures used by this module ****/ static XPRMnifct mm; /* For storing Mosel NI function table */ typedef struct Task /* A task */ { int refcnt; const char *name; int aflag,duedate; double duration; struct Task *next; } s_task; typedef struct /* Context of this module */ { s_task *firsttask; int maxname; double maxtime; } s_taskctx; static struct /* Parameters published by this module */ { char *name; int type; char *desc; } taskparams[]={ {"taskmaxtime",XPRM_TYP_REAL|XPRM_CPAR_READ|XPRM_CPAR_WRITE, "a time limit value"}, {"tasknamelength",XPRM_TYP_INT|XPRM_CPAR_READ|XPRM_CPAR_WRITE, "maximum length of task names"} }; /*******************************************************/ /* Initialize the module library just after loading it */ /*******************************************************/ DSO_INIT task_init(XPRMnifct nifct, int *interver,int *libver, XPRMdsointer **interf) { mm=nifct; /* Save the table of Mosel NI functions */ *interver=XPRM_NIVERS; /* Mosel NI version */ *libver=XPRM_MKVER(0,0,1); /* Module version */ *interf=&dsointer; /* Pass info about module contents to Mosel */ return 0; } /******** Functions implementing subroutines and operators ********/ /*******************************/ /* Getting a control parameter */ /*******************************/ static int task_getpar(XPRMcontext ctx,void *libctx) { s_taskctx *taskctx; int n; taskctx=libctx; n=XPRM_POP_INT(ctx); switch(n) { case 0: XPRM_PUSH_INT(ctx,taskctx->maxname); break; case 1: XPRM_PUSH_REAL(ctx,taskctx->maxtime); break; default: mm->dispmsg(ctx,"Task: Wrong control parameter number.\n"); return XPRM_RT_ERROR; } return XPRM_RT_OK; } /*******************************/ /* Setting a control parameter */ /*******************************/ static int task_setpar(XPRMcontext ctx,void *libctx) { s_taskctx *taskctx; int n; taskctx=libctx; n=XPRM_POP_INT(ctx); switch(n) { case 0: taskctx->maxname=XPRM_POP_INT(ctx); break; case 1: taskctx->maxtime=XPRM_POP_REAL(ctx); break; default: mm->dispmsg(ctx,"Task: Wrong control parameter number.\n"); return XPRM_RT_ERROR; } /* Test to be added if there are any read-only parameters: if(!(taskparams[n].type&XPRM_CPAR_WRITE)) { mm->dispmsg(ctx,"Task: Control parameter is read-only.\n")); return XPRM_RT_ERROR; } else */ return XPRM_RT_OK; } /*************************/ /* Getting the task name */ /*************************/ 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; } /*****************************/ /* Getting the task duration */ /*****************************/ static int task_getdur(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_REAL(ctx,task->duration); return XPRM_RT_OK; } /*************************/ /* Getting the task flag */ /*************************/ static int task_getaflag(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_INT(ctx,task->aflag); return XPRM_RT_OK; } /*****************************/ /* Getting the task due date */ /*****************************/ static int task_getdue(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_INT(ctx,task->duedate); return XPRM_RT_OK; } /*************************/ /* Setting the task name */ /*************************/ static int task_setname(XPRMcontext ctx,void *libctx) { s_task *task; const char *name; task=XPRM_POP_REF(ctx); name=XPRM_POP_STRING(ctx); if(task==NULL) { mm->dispmsg(ctx,"Task: Accessing undefined task.\n"); return XPRM_RT_ERROR; } task->name=name; return XPRM_RT_OK; } /*****************************/ /* Setting the task 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; } /*************************/ /* Setting the task flag */ /*************************/ static int task_setaflag(XPRMcontext ctx,void *libctx) { s_task *task; int af; task=XPRM_POP_REF(ctx); af=XPRM_POP_INT(ctx); if(task==NULL) { mm->dispmsg(ctx,"Task: Accessing undefined task.\n"); return XPRM_RT_ERROR; } task->aflag=af; return XPRM_RT_OK; } /*****************************/ /* Setting the task due date */ /*****************************/ static int task_setdue(XPRMcontext ctx,void *libctx) { s_task *task; int due; task=XPRM_POP_REF(ctx); due=XPRM_POP_INT(ctx); if(task==NULL) { mm->dispmsg(ctx,"Task: Accessing undefined task.\n"); return XPRM_RT_ERROR; } task->duedate=due; return XPRM_RT_OK; } /****************/ /* Clone a task */ /****************/ 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; } /************************************************/ /* Create a task with */ /* 1 - name given */ /* 2 - duration given */ /* 3 - name and duration given */ /* 4 - name, duration, aflag, and duedate given */ /* 5 - duration, aflag, and duedate given */ /************************************************/ static int task_new1(XPRMcontext ctx,void *libctx) { s_task *task; task=task_create(ctx,libctx,NULL,0); task->name=XPRM_POP_STRING(ctx); XPRM_PUSH_REF(ctx,task); return XPRM_RT_OK; } static int task_new2(XPRMcontext ctx,void *libctx) { s_task *task; task=task_create(ctx,libctx,NULL,0); task->duration=XPRM_POP_REAL(ctx); XPRM_PUSH_REF(ctx,task); return XPRM_RT_OK; } static int task_new3(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); XPRM_PUSH_REF(ctx,task); return XPRM_RT_OK; } 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; } static int task_new5(XPRMcontext ctx,void *libctx) { s_task *task; task=task_create(ctx,libctx,NULL,0); 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; } /*************************/ /* Assignment task:=task */ /*************************/ 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; } /***************************/ /* Comparison of two tasks */ /***************************/ 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) /* This comparison is correct since we are using Mosel's dictionary */ &&(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; } /**************** Type-related functions ****************/ /*****************************/ /* Allocate space for a task */ /*****************************/ static void *task_create(XPRMcontext ctx,void *libctx,void *todup,int typnum) { s_taskctx *taskctx; s_task *task; if(todup!=NULL) { ((s_task *)todup)->refcnt++; return todup; } else { taskctx=libctx; task=(s_task *)malloc(sizeof(s_task)); task->next=taskctx->firsttask; taskctx->firsttask=task; task->refcnt=1; task->name=NULL; /* Initialize the task */ task->duration=0; task->aflag=task->duedate=0; return task; } } /*********************/ /* Deallocate a task */ /*********************/ static void task_delete(XPRMcontext ctx,void *libctx,void *todel,int typnum) { s_taskctx *taskctx; s_task *task,*prev; if((todel!=NULL)&&((--((s_task *)todel)->refcnt)<1)) { taskctx=libctx; task=todel; if(taskctx->firsttask==task) taskctx->firsttask=task->next; else { prev=taskctx->firsttask; while((prev->next!=NULL) && (prev->next!=task)) prev=prev->next; if(prev->next==NULL) mm->dispmsg(ctx,"Task: task not found.\n"); else prev->next=task->next; } free(task); } } /******************/ /* Task -> String */ /******************/ static int task_tostr(XPRMcontext ctx,void *libctx,void *toprt,char *str,int len,int typnum) { s_task *task; if(toprt==NULL) return 0; else { task=toprt; return snprintf(str,len,"%s %g %d %d",(task->name!=NULL)?task->name:"anon", task->duration,task->aflag,task->duedate); } } /******************/ /* String -> Task */ /******************/ static int task_fromstr(XPRMcontext ctx,void *libctx,void *toinit, const char *str,int typnum, const char **endp) { double dur; int af,due,res,cnt; char *name; s_taskctx *taskctx; s_task *task; struct Info { char dummy[4]; s_task *t; } *ref; taskctx=libctx; task=toinit; if((str[0]=='r') && (str[1]=='a') && (str[2]=='w') && (str[3]=='\0')) { if(endp!=NULL) *endp=NULL; ref=(struct Info *)str; if(ref->t==NULL) return RT_ERROR; else { task->name=ref->t->name; task->aflag=ref->t->aflag; task->duedate=ref->t->duedate; task->duration=ref->t->duration; } return XPRM_RT_OK; } else { name=(char *)alloca((taskctx->maxname)*sizeof(char)); af=due=cnt=0; res=sscanf(str,"%s %lf %d%n %d%n",name,&dur,&af,&cnt,&due,&cnt); if(res<3) { if(endp!=NULL) *endp=str; return XPRM_RT_ERROR; } else { task->name=mm->regstring(ctx,name); task->duration=dur; task->aflag=af; task->duedate=due; if(endp!=NULL) *endp=str+cnt; return XPRM_RT_OK; } } } /***************/ /* Copy a task */ /***************/ static int task_copy(XPRMcontext ctx,void *libctx,void *toinit,void *src,int typnum) { s_task *task1,*task2; task1=(s_task *)toinit; if(src==NULL) { task1->name=NULL; task1->duration=0; task1->aflag=task1->duedate=0; } else { task2=(s_task *)src; task1->name=task2->name; task1->aflag=task2->aflag; task1->duedate=task2->duedate; task1->duration=task2->duration; } return 0; } /******************** Services ********************/ /****************************/ /* Find a control parameter */ /****************************/ static int task_findparam(const char *name,int *type) { int n; int notfound; n=0; do { if((notfound=strcmp(name,taskparams[n].name))==0) break; n++; } while(taskparams[n].name!=NULL); if(!notfound) { *type=taskparams[n].type; return n; } else return -1; } /*********************************************/ /* Return the next parameter for enumeration */ /*********************************************/ static void *task_nextparam(void *ref,const char **name,const char **desc, int *type) { long cst; cst=(long)ref; if((cst<0)||(cst>=TASK_NUMPARAM)) return NULL; else { *name=taskparams[cst].name; *type=taskparams[cst].type; *desc=taskparams[cst].desc; return (void *)(cst+1); } } /*************************/ /* Reset the Task module */ /*************************/ static void *task_reset(XPRMcontext ctx,void *libctx,int version) { s_taskctx *taskctx; s_task *task; if(libctx==NULL) /* At start: create the context, allocate space */ { taskctx=malloc(sizeof(s_taskctx)); memset(taskctx,0,sizeof(s_taskctx)); taskctx->maxname=TASK_MAXNAME; taskctx->maxtime=TASK_MAXTIME; return taskctx; } else /* At the end: delete everything */ { taskctx=libctx; while(taskctx->firsttask!=NULL) { task=taskctx->firsttask; taskctx->firsttask=task->next; free(task); } free(taskctx); return NULL; } } | |||||||||||
© Copyright 2024 Fair Isaac Corporation. |