TPCCLIB
Loading...
Searching...
No Matches
par.c File Reference

PAR struct processing. More...

#include "tpcclibConfig.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <string.h>
#include "tpcextensions.h"
#include "tpcmodels.h"
#include "tpcift.h"
#include "tpcpar.h"

Go to the source code of this file.

Functions

void parInit (PAR *par)
 
void parrInit (PARR *parr)
 
void parnInit (PARN *parn)
 
void parFree (PAR *par)
 
void parrFree (PARR *parr)
 
int parAllocate (PAR *par, int parNr, int tacNr)
 
int parrAllocate (PARR *parr, int parNr)
 
int parAllocateMore (PAR *par, int parNr, int tacNr)
 
int parIsWSS (PAR *par)
 
int parIsFitRange (PAR *par)
 
int parIsModel (PAR *par)
 
int parSDWithPar (PAR *par, int pi)
 
int parCLWithPar (PAR *par, int pi)
 
int parIsFitNr (PAR *par)
 
int parIsDataNr (PAR *par)
 
char * parIsOptcrit (PAR *par)
 
char * parIsStudyNr (PAR *par)
 
int parSetStudyNr (PAR *par, const char *s)
 
void parEnsureNames (PAR *d)
 
int parDeletePar (PAR *par, int pi)
 
int parDeleteTAC (PAR *par, int ti)
 

Detailed Description

PAR struct processing.

Definition in file par.c.

Function Documentation

◆ parAllocate()

int parAllocate ( PAR * par,
int parNr,
int tacNr )

Allocate memory for PAR data.

Any previous contents are deleted.

Returns
Returns TPCERROR status.
See also
parInit, parFree, parAllocateMore, parAllocateWithTAC
Parameters
parPointer to initiated PAR struct data; any old contents are deleted. tacNr and parNr inside the struct are set to or kept at zero.
parNrNr of parameters to allocate
tacNrNr of parameter sets (TACs) to allocate

Definition at line 108 of file par.c.

116 {
117 if(par==NULL) return TPCERROR_FAIL;
118 /* Delete any previous contents */
119 parFree(par);
120 /* If no memory is requested, then just return */
121 if(parNr<1 && tacNr<1) return TPCERROR_OK;
122 if(parNr<1 || tacNr<1) return TPCERROR_FAIL;
123
124 /* Allocate memory for PARR data */
125 int ret;
126 par->r=(PARR*)malloc(tacNr*sizeof(PARR));
127 if(par->r==NULL) return TPCERROR_OUT_OF_MEMORY;
128 for(int i=0; i<tacNr; i++) {
129 parrInit(&par->r[i]);
130 ret=parrAllocate(par->r+i, parNr); if(ret!=TPCERROR_OK) return ret;
131 }
132 par->_tacNr=tacNr;
133
134 /* Allocate memory for parameter names and units */
135 par->n=(PARN*)malloc(parNr*sizeof(PARN));
136 if(par->n==NULL) return TPCERROR_OUT_OF_MEMORY;
137 for(int i=0; i<parNr; i++) parnInit(&par->n[i]);
138 par->_parNr=parNr;
139
140 return TPCERROR_OK;
141}
void parFree(PAR *par)
Definition par.c:75
int parrAllocate(PARR *parr, int parNr)
Definition par.c:150
void parrInit(PARR *parr)
Definition par.c:41
void parnInit(PARN *parn)
Definition par.c:59
int _parNr
Definition tpcpar.h:111
PARR * r
Definition tpcpar.h:115
int _tacNr
Definition tpcpar.h:107
PARN * n
Definition tpcpar.h:113
Definition tpcpar.h:81
Definition tpcpar.h:46
@ TPCERROR_FAIL
General error.
@ TPCERROR_OUT_OF_MEMORY
Cannot allocate memory.
@ TPCERROR_OK
No error.

Referenced by parAllocateWithTAC(), parExamplePerfectBolus(), parExampleTTACs(), parFromIFT(), parReadCSV(), parReadFIT(), and parReadRES().

◆ parAllocateMore()

int parAllocateMore ( PAR * par,
int parNr,
int tacNr )

Allocate more memory for PAR data. Previous contents are preserved.

Returns
Returns TPCERROR status.
See also
parAllocate, parInit, parRead, parFree
Parameters
parPointer to initiated and previously allocated PAR struct data; any old contents are preserved, including tacNr and parNr.
parNrNr of additional parameters to allocate; if struct contains unused space for requested parameters already, then nothing is done.
tacNrNr of additional parameter sets (TACs) to allocate; if struct contains unused space for requested parameters already, then nothing is done.

Definition at line 183 of file par.c.

193 {
194 if(par==NULL) return TPCERROR_FAIL;
195 if(par->_parNr<1 || par->_tacNr<1) return TPCERROR_FAIL;
196 if(parNr<0 || tacNr<0) return TPCERROR_FAIL;
197 /* Check if there is enough space already */
198 int newTacNr, addTacNr, newParNr, addParNr;
199 newTacNr=par->tacNr+tacNr; addTacNr=newTacNr-par->_tacNr;
200 newParNr=par->parNr+parNr; addParNr=newParNr-par->_parNr;
201 if(addTacNr<=0 && addParNr<=0) return TPCERROR_OK;
202
203 /* Reallocate memory for parameter names and units, if necessary */
204 if(addParNr>0) {
205 PARN *parnPtr;
206 parnPtr=realloc(par->n, sizeof(PARN)*newParNr);
207 if(parnPtr==NULL) return TPCERROR_OUT_OF_MEMORY;
208 par->n=parnPtr;
209 parnPtr+=par->_parNr; for(int i=0; i<addParNr; i++) parnInit(parnPtr++);
210 }
211
212 /* Reallocate memory for parameters of previous TACs, if necessary */
213 if(addParNr>0) {
214 int i, j;
215 for(i=0; i<par->tacNr; i++) {
216 par->r[i].p=realloc(par->r[i].p, sizeof(double)*newParNr);
217 par->r[i].sd=realloc(par->r[i].sd, sizeof(double)*newParNr);
218 par->r[i].cl1=realloc(par->r[i].cl1, sizeof(double)*newParNr);
219 par->r[i].cl2=realloc(par->r[i].cl2, sizeof(double)*newParNr);
220 if(par->r[i].p==NULL || par->r[i].sd==NULL || par->r[i].cl1==NULL || par->r[i].cl2==NULL)
222 for(j=par->parNr; j<newParNr; j++)
223 par->r[i].p[j]=par->r[i].sd[j]=par->r[i].cl1[j]=par->r[i].cl2[j]=nan("");
224 }
225 }
226
227 /* Allocate memory for more TACs, if necessary */
228 if(addTacNr>0) {
229 PARR *parrPtr;
230 parrPtr=realloc(par->r, sizeof(PARR)*newTacNr);
231 if(parrPtr==NULL) return TPCERROR_OUT_OF_MEMORY;
232 par->r=parrPtr;
233 parrPtr+=par->_tacNr;
234 for(int i=0; i<addTacNr; i++, parrPtr++) {
235 parrInit(parrPtr);
236 if(parrAllocate(parrPtr, newParNr)!=TPCERROR_OK)
238 }
239 }
240
241 par->_parNr=newParNr;
242 par->_tacNr=newTacNr;
243 return TPCERROR_OK;
244}
int parNr
Definition tpcpar.h:109
int tacNr
Definition tpcpar.h:105
double * cl2
Definition tpcpar.h:71
double * p
Definition tpcpar.h:65
double * sd
Definition tpcpar.h:67
double * cl1
Definition tpcpar.h:69

Referenced by parCombineTACs().

◆ parCLWithPar()

int parCLWithPar ( PAR * par,
int pi )

Check if specified parameter has confidence limits in at least one of the regions.

See also
parSDWithPar, parIsWSS
Returns
Returns 1 if CLs exist, and 0 if not (or in case of an error).
Parameters
parPointer to parameter data.
piIndex of parameter [0..parNr-1] to check.

Definition at line 325 of file par.c.

330 {
331 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(0);
332 for(int i=0; i<par->tacNr; i++)
333 if(!isnan(par->r[i].cl1[pi]) && !isnan(par->r[i].cl2[pi])) return(1);
334 return(0);
335}

Referenced by parWriteCSV(), and parWriteXML().

◆ parDeletePar()

int parDeletePar ( PAR * par,
int pi )

Deletes the specified parameter (column) from data.

Returns
Returns TPCERROR status.
See also
parDeleteTAC
Parameters
parPointer to parameter data.
piIndex of parameter [0..parNr-1] to remove.

Definition at line 478 of file par.c.

483 {
484 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(TPCERROR_FAIL);
485 if(pi==par->parNr-1) {par->parNr--; return(TPCERROR_OK);}
486
487 int i, j;
488
489 /* Parameter name and unit */
490 PARN parn;
491 memcpy(&parn, &par->n[pi], sizeof(PARN));
492 for(i=pi+1; i<par->parNr; i++)
493 memcpy(&par->n[i-1], &par->n[i], sizeof(PARN));
494 memcpy(&par->n[par->parNr-1], &parn, sizeof(PARN));
495
496 /* Parameter values */
497 double p, sd, cl1, cl2;
498 for(j=0; j<par->tacNr; j++) {
499 p=par->r[j].p[pi]; sd=par->r[j].sd[pi];
500 cl1=par->r[j].cl1[pi]; cl2=par->r[j].cl2[pi];
501 for(i=pi+1; i<par->parNr; i++) {
502 par->r[j].p[i-1]=par->r[j].p[i]; par->r[j].sd[i-1]=par->r[j].sd[i];
503 par->r[j].cl1[i-1]=par->r[j].cl1[i]; par->r[j].cl2[i-1]=par->r[j].cl2[i];
504 }
505 par->r[j].p[par->parNr-1]=p; par->r[j].sd[par->parNr-1]=sd;
506 par->r[j].cl1[par->parNr-1]=cl1; par->r[j].cl2[par->parNr-1]=cl2;
507 }
508
509 par->parNr--;
510 return(TPCERROR_OK);
511}

Referenced by parReadCSV(), and parReadRES().

◆ parDeleteTAC()

int parDeleteTAC ( PAR * par,
int ti )

Deletes the specified TAC (row) from data.

Returns
Returns TPCERROR status.
See also
parDeletePar, parSortByName
Parameters
parPointer to parameter data.
tiIndex of TAC [0..tacNr-1] to remove.

Definition at line 519 of file par.c.

524 {
525 if(par==NULL || par->tacNr<1 || ti<0 || ti>=par->tacNr) return(TPCERROR_FAIL);
526 /* Free the memory allocated for the TAC */
527 parrFree(par->r+ti);
528 /* If the last TAC is to be deleted, then just reduce the tacNr */
529 if(ti==par->tacNr-1) {par->tacNr--; return(TPCERROR_OK);}
530 /* Otherwise move the following TACs in its place */
531 for(int i=ti+1; i<par->tacNr; i++) par->r[i-1]=par->r[i];
532 par->tacNr--; parrInit(par->r+par->tacNr);
533 return(TPCERROR_OK);
534}
void parrFree(PARR *parr)
Definition par.c:87

◆ parEnsureNames()

void parEnsureNames ( PAR * d)

Ensure that PAR struct contains a name for each TAC and parameters. If not available, then index+1 is written as name.

See also
parSetStudyNr, parSortByName
Parameters
dPointer to parameter data.

Definition at line 449 of file par.c.

452 {
453 if(d==NULL || d->tacNr<1 || d->parNr<1) return;
454 /* Ensure TAC names */
455 int u, n;
456 u=d->tacNr; n=1; while((u/=10)>=1) n++;
458 for(int i=0; i<d->tacNr; i++) {
459 if(strlen(d->r[i].name)<1 || strcmp(d->r[i].name, ".")==0)
460 sprintf(d->r[i].name, "%0*d", n, 1+i);
461 }
462 /* Ensure parameter names */
463 u=d->parNr; n=1; while((u/=10)>=1) n++;
465 for(int i=0; i<d->parNr; i++) {
466 if(strlen(d->n[i].name)<1 || strcmp(d->n[i].name, ".")==0)
467 sprintf(d->n[i].name, "P%0*d", n, 1+i);
468 }
469 return;
470}
char name[MAX_PARNAME_LEN+1]
Definition tpcpar.h:83
char name[MAX_TACNAME_LEN+1]
Definition tpcpar.h:50
#define MAX_TACNAME_LEN
Max length of TAC ID name (not including trailing zero)
#define MAX_PARNAME_LEN
Max string length for PAR name.

◆ parFree()

void parFree ( PAR * par)

Free memory allocated for PAR. All data is cleared.

See also
parInit, parAllocate, parRead
Parameters
parPointer to PAR struct

Definition at line 75 of file par.c.

78 {
79 if(par==NULL) return;
80 for(int i=0; i<par->_tacNr; i++) parrFree(par->r+i);
81 free(par->r);
82 free(par->n);
83 iftFree(&par->h);
84 parInit(par);
85}
void iftFree(IFT *ift)
Definition ift.c:37
void parInit(PAR *par)
Definition par.c:25
IFT h
Optional (but often useful) header information.
Definition tpcpar.h:148

Referenced by parAllocate(), parFromIFT(), parRead(), parReadCSV(), parReadFIT(), and parReadRES().

◆ parInit()

void parInit ( PAR * par)

Initiate the PAR struct before any use.

Author
Vesa Oikonen
See also
parrInit, parnInit, parFree, parAllocate, parRead
Parameters
parPointer to PAR

Definition at line 25 of file par.c.

28 {
29 if(par==NULL) return;
31 par->tacNr=par->_tacNr=0;
32 par->parNr=par->_parNr=0;
33 par->n=NULL;
34 par->r=NULL;
35 iftInit(&par->h);
36}
void iftInit(IFT *ift)
Definition ift.c:21
int format
Definition tpcpar.h:103
@ PAR_FORMAT_UNKNOWN
Unknown format.
Definition tpcpar.h:28

Referenced by parFree().

◆ parIsDataNr()

int parIsDataNr ( PAR * par)

Check if any of parameter sets has dataNr specified.

See also
parIsFitNr, parIsWSS
Returns
Returns 0 if not, 1 if the same in each set, and 2 if variable.
Parameters
parPointer to parameter data

Definition at line 362 of file par.c.

365 {
366 if(par==NULL || par->tacNr<1) return(0);
367 int ri, ret=0;
368 for(ri=0; ri<par->tacNr; ri++) {
369 if(ret==0 && par->r[ri].dataNr>0) ret=1;
370 if(ri>0 && par->r[ri].dataNr!=par->r[ri-1].dataNr) {ret=2; break;}
371 }
372 return(ret);
373}
int dataNr
Definition tpcpar.h:63

Referenced by parToIFT(), parWriteCSV(), and parWriteXML().

◆ parIsFitNr()

int parIsFitNr ( PAR * par)

Check if any of parameter sets has fitNr specified.

See also
parIsDataNr, parIsWSS
Returns
Returns 0 if not, 1 if the same in each set, and 2 if variable.
Parameters
parPointer to parameter data.

Definition at line 343 of file par.c.

346 {
347 if(par==NULL || par->tacNr<1) return(0);
348 int ri, ret=0;
349 for(ri=0; ri<par->tacNr; ri++) {
350 if(ret==0 && par->r[ri].fitNr>0) ret=1;
351 if(ri>0 && par->r[ri].fitNr!=par->r[ri-1].fitNr) {ret=2; break;}
352 }
353 return(ret);
354}
int fitNr
Definition tpcpar.h:59

Referenced by parToIFT(), parWriteCSV(), and parWriteXML().

◆ parIsFitRange()

int parIsFitRange ( PAR * par)

Check if any of parameter sets has fit range specified.

See also
parIsFitNr, parIsDataNr, parIsWSS
Returns
Returns 0 if not, 1 if the same in each set, and 2 if variable.
Parameters
parPointer to parameter data.

Definition at line 267 of file par.c.

270 {
271 if(par==NULL || par->tacNr<1) return(0);
272 int ri, ret=0;
273 for(ri=0; ri<par->tacNr; ri++) {
274 if(!isnan(par->r[ri].start) || !isnan(par->r[ri].end)) ret=1;
275 if(ri==0 || ret==0) continue;
276 if(!doubleMatch(par->r[ri].start, par->r[0].start, 0.01)) {ret=2; break;}
277 if(!doubleMatch(par->r[ri].end, par->r[0].end, 0.01)) {ret=2; break;}
278 }
279 return(ret);
280}
int doubleMatch(const double v1, const double v2, const double lim)
Definition doubleutil.c:27
double start
Definition tpcpar.h:52
double end
Definition tpcpar.h:54

Referenced by parToIFT(), parWriteCSV(), and parWriteXML().

◆ parIsModel()

int parIsModel ( PAR * par)

Check if any of parameter sets has model id specified.

See also
parIsFitNr, parIsWSS, parRead, parIsOptcrit
Returns
Returns 0 if not, 1 if the same in each set, and 2 if variable.
Parameters
parPointer to parameter data.

Definition at line 288 of file par.c.

291 {
292 if(par==NULL || par->tacNr<1) return(0);
293 int ri, ret=0;
294 for(ri=0; ri<par->tacNr; ri++) {
295 if(ret==0 && par->r[ri].model>0) ret=1;
296 if(ri>0 && par->r[ri].model!=par->r[ri-1].model) {ret=2; break;}
297 }
298 return(ret);
299}
unsigned int model
Definition tpcpar.h:48

Referenced by parToIFT(), parWriteCSV(), and parWriteXML().

◆ parIsOptcrit()

char * parIsOptcrit ( PAR * par)

Check if PAR data contains optimality criterion.

See also
parIsModel, parIsWSS, studynrFromFilename
Returns
Returns pointer to optimization criterion name, or NULL if not found.
Parameters
parPointer to parameter data.

Definition at line 381 of file par.c.

384 {
385 if(par==NULL || par->h.keyNr<1) return((char*)NULL);
386 int li=iftFindKey(&par->h, "optimality_criterion", 0);
387 if(li<0) li=iftFindKey(&par->h, "optcrit", 0);
388 if(li<0) return((char*)NULL);
389 if(par->h.item[li].value==NULL || strlen(par->h.item[li].value)<1) return((char*)NULL);
390 return(par->h.item[li].value);
391}
int iftFindKey(IFT *ift, const char *key, int start_index)
Definition iftfind.c:30
char * value
Definition tpcift.h:37
IFT_ITEM * item
Definition tpcift.h:57
int keyNr
Definition tpcift.h:47

◆ parIsStudyNr()

char * parIsStudyNr ( PAR * par)

Check if PAR data contains study number.

See also
parSetStudyNr, parIsModel, parIsWSS, studynrFromFilename, parEnsureNames
Returns
Returns pointer to study number, or NULL if not found.
Parameters
parPointer to parameter data.

Definition at line 399 of file par.c.

402 {
403 if(par==NULL || par->h.keyNr<1) return((char*)NULL);
404 int li=iftFindKey(&par->h, "studynr", 0);
405 if(li<0) li=iftFindKey(&par->h, "study_number", 0);
406 if(li<0) return((char*)NULL);
407 if(par->h.item[li].value==NULL || strlen(par->h.item[li].value)<1) return((char*)NULL);
408 return(par->h.item[li].value);
409}

◆ parIsWSS()

int parIsWSS ( PAR * par)

Check if any of parameter sets has WSS.

See also
parIsFitNr, parIsDataNr, parCLWithPar, parSDWithPar, parIsOptcrit
Returns
Returns 1 if WSS exists, and 0 if not (or in case of an error).
Parameters
parPointer to parameter data.

Definition at line 252 of file par.c.

255 {
256 if(par==NULL || par->tacNr<1) return(0);
257 for(int ri=0; ri<par->tacNr; ri++) if(!isnan(par->r[ri].wss)) return(1);
258 return(0);
259}
double wss
Definition tpcpar.h:73

Referenced by parWriteCSV(), parWriteRES(), and parWriteXML().

◆ parnInit()

void parnInit ( PARN * parn)

Initiate the PARN struct before any use.

Author
Vesa Oikonen
See also
parInit, parrInit
Parameters
parnPointer to PARN

Definition at line 59 of file par.c.

62 {
63 if(parn==NULL) return;
64 parn->name[0]='\0';
65 parn->unit=UNIT_UNKNOWN;
66 parn->lim1=parn->lim2=parn->tol=nan("");
67 parn->sw=0;
68}
int unit
Definition tpcpar.h:87
double lim2
Definition tpcpar.h:91
char sw
Definition tpcpar.h:95
double tol
Definition tpcpar.h:93
double lim1
Definition tpcpar.h:89
@ UNIT_UNKNOWN
Unknown unit.

Referenced by parAllocate(), and parAllocateMore().

◆ parrAllocate()

int parrAllocate ( PARR * parr,
int parNr )

Allocate memory for PARR data. Any previous contents are deleted.

See also
parrInit, parrFree, parAllocate
Returns
Returns TPCERROR status.
Parameters
parrPointer to initiated PARR struct data; any old contents are deleted.
parNrNr of parameters to allocate.

Definition at line 150 of file par.c.

155 {
156 if(parr==NULL) return TPCERROR_FAIL;
157 /* Delete any previous contents */
158 parrFree(parr);
159 /* If no memory is requested, then just return */
160 if(parNr<1) return TPCERROR_OK;
161
162 /* Allocate memory for PARR data */
163 parr->p=malloc(parNr*sizeof(double));
164 parr->sd=malloc(parNr*sizeof(double));
165 parr->cl1=malloc(parNr*sizeof(double));
166 parr->cl2=malloc(parNr*sizeof(double));
167 if(parr->p==NULL || parr->sd==NULL || parr->cl1==NULL || parr->cl2==NULL)
169 /* Initiate values to NaNs */
170 for(int i=0; i<parNr; i++)
171 parr->p[i]=parr->sd[i]=parr->cl1[i]=parr->cl2[i]=nan("");
172
173 return TPCERROR_OK;
174}

Referenced by parAllocate(), and parAllocateMore().

◆ parrFree()

void parrFree ( PARR * parr)

Free memory allocated for PARR. All data is cleared.

Parameters
parrPointer to PARR struct

Definition at line 87 of file par.c.

90 {
91 if(parr==NULL) return;
92 free(parr->p);
93 free(parr->sd);
94 free(parr->cl1);
95 free(parr->cl2);
96 parrInit(parr);
97}

Referenced by parDeleteTAC(), parFree(), and parrAllocate().

◆ parrInit()

void parrInit ( PARR * parr)

Initiate the PARR struct before any use.

Author
Vesa Oikonen
See also
parInit, parnInit
Parameters
parrPointer to PARR

Definition at line 41 of file par.c.

44 {
45 if(parr==NULL) return;
46 parr->model=0;
47 parr->name[0]='\0';
48 parr->start=parr->end=nan("");
49 parr->fitNr=0;
50 parr->dataNr=0;
51 parr->p=parr->sd=parr->cl1=parr->cl2=NULL;
52 parr->wss=nan("");
53 parr->sw=0;
54}
char sw
Definition tpcpar.h:75

Referenced by parAllocate(), parAllocateMore(), parDeleteTAC(), and parrFree().

◆ parSDWithPar()

int parSDWithPar ( PAR * par,
int pi )

Check if specified parameter has SD in at least one of the regions.

See also
parCLWithPar, parIsWSS
Returns
Returns 1 if SD exists, and 0 if not (or in case of an error).
Parameters
parPointer to parameter data.
piIndex of parameter [0..parNr-1] to check.

Definition at line 307 of file par.c.

312 {
313 //printf("%s(%d)\n", __func__, pi); fflush(stdout);
314 if(par==NULL || par->tacNr<1 || pi<0 || pi>=par->parNr) return(0);
315 for(int i=0; i<par->tacNr; i++) if(!isnan(par->r[i].sd[pi])) return(1);
316 return(0);
317}

Referenced by parWriteCSV(), and parWriteXML().

◆ parSetStudyNr()

int parSetStudyNr ( PAR * par,
const char * s )

Set study number in PAR data, overwriting any previous study number.

See also
parIsStudyNr, tacSetHeaderStudynr, tacGetHeaderStudynr, studynrFromFilename
Returns
enum tpcerror (TPCERROR_OK when successful).
Parameters
parPointer to parameter data.
sPointer to string containing the study number; enter NULL or "" if you only want to delete studynr in header.

Definition at line 417 of file par.c.

423 {
424 if(par==NULL) return TPCERROR_FAIL;
425
426 /* Find and delete previous studynr(s) */
427 int i=0, start=0;
428 while(1) {
429 i=iftFindKey(&par->h, "studynr", start);
430 if(i<0) i=iftFindKey(&par->h, "study_number", start);
431 if(i<0) i=iftFindKey(&par->h, "study number", start);
432 if(i<0) break;
433 iftDelete(&par->h, i); if(i>start) start=i;
434 }
435
436 /* If new studynr is empty, then just return */
437 if(s==NULL || *s=='\0') return(TPCERROR_OK);
438
439 /* Otherwise create new key and value */
440 return(iftPut(&par->h, "studynr", s, (char)1, NULL));
441}
int iftPut(IFT *ift, const char *key, const char *value, char comment, TPCSTATUS *status)
Definition ift.c:63
int iftDelete(IFT *ift, int index)
Definition ift.c:206