/* File: exprval.c Auth: Brian Allen Vanderburg II Date: Thursday, April 24, 2003 Desc: Value lists for variables and constants This file is part of ExprEval. */ /* Includes */ #include "exprincl.h" #include "exprpriv.h" #include "exprmem.h" /* Internal functions */ static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr); static void exprValListFreeData(exprVal *val); static void exprValListResetData(exprVal *val); /* This function creates the value list, */ int exprValListCreate(exprValList **vlist) { exprValList *tmp; if(vlist == NULL) return EXPR_ERROR_NULLPOINTER; *vlist = NULL; /* Set to NULL initially */ tmp = exprAllocMem(sizeof(exprValList)); if(tmp == NULL) return EXPR_ERROR_MEMORY; /* Could not allocate memory */ /* Update pointer */ *vlist = tmp; return EXPR_ERROR_NOERROR; } /* Add a value to the list */ int exprValListAdd(exprValList *vlist, char *name, EXPRTYPE val) { exprVal *tmp; exprVal *cur; int result; if(vlist == NULL) return EXPR_ERROR_NULLPOINTER; /* Make sure the name is valid */ if(!exprValidIdent(name)) return EXPR_ERROR_BADIDENTIFIER; if(vlist->head == NULL) { /* Create the node right here */ tmp = exprCreateVal(name, val, NULL); if(tmp == NULL) return EXPR_ERROR_MEMORY; vlist->head = tmp; return EXPR_ERROR_NOERROR; } /* See if already exists */ cur = vlist->head; while(cur) { result = strcmp(name, cur->vname); if(result == 0) return EXPR_ERROR_ALREADYEXISTS; cur = cur->next; } /* We did not find it, create it and add it to the beginning */ tmp = exprCreateVal(name, val, NULL); if(tmp == NULL) return EXPR_ERROR_MEMORY; tmp->next = vlist->head; vlist->head = tmp; return EXPR_ERROR_NOERROR; } /* Set a value in the list */ int exprValListSet(exprValList *vlist, char *name, EXPRTYPE val) { exprVal *cur; int result; if(vlist == NULL) return EXPR_ERROR_NULLPOINTER; if(name == NULL || name[0] == '\0') return EXPR_ERROR_NOTFOUND; /* Find and set it */ cur = vlist->head; while(cur) { result = strcmp(name, cur->vname); if(result == 0) { if(cur->vptr) *(cur->vptr) = val; else cur->vval = val; return EXPR_ERROR_NOERROR; } cur = cur->next; } return EXPR_ERROR_NOTFOUND; } /* Get the value from a list */ int exprValListGet(exprValList *vlist, char *name, EXPRTYPE *val) { exprVal *cur; int result; if(vlist == NULL) return EXPR_ERROR_NULLPOINTER; if(name == NULL || name[0] == '\0') return EXPR_ERROR_NOTFOUND; /* Search for the item */ cur = vlist->head; while(cur) { result = strcmp(name, cur->vname); if(result == 0) { /* We found it. */ if(cur->vptr) *val = *(cur->vptr); else *val = cur->vval; /* return now */ return EXPR_ERROR_NOERROR; } cur = cur->next; } /* If we got here, we did not find the item in the list */ return EXPR_ERROR_NOTFOUND; } /* Add an address to the list */ int exprValListAddAddress(exprValList *vlist, char *name, EXPRTYPE *addr) { exprVal *tmp; exprVal *cur; int result; if(vlist == NULL) return EXPR_ERROR_NULLPOINTER; /* Make sure the name is valid */ if(!exprValidIdent(name)) return EXPR_ERROR_BADIDENTIFIER; if(vlist->head == NULL) { /* Create the node right here */ tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr); if(tmp == NULL) return EXPR_ERROR_MEMORY; vlist->head = tmp; return EXPR_ERROR_NOERROR; } /* See if it already exists */ cur = vlist->head; while(cur) { result = strcmp(name, cur->vname); if(result == 0) return EXPR_ERROR_ALREADYEXISTS; cur = cur->next; } /* Add it to the list */ tmp = exprCreateVal(name, (EXPRTYPE)0.0, addr); if(tmp == NULL) return EXPR_ERROR_MEMORY; tmp->next = vlist->head; vlist->head = tmp; return EXPR_ERROR_NOERROR; } /* Get memory address of a variable value in a value list */ int exprValListGetAddress(exprValList *vlist, char *name, EXPRTYPE **addr) { exprVal *cur; int result; /* Not found yet */ *addr = NULL; if(vlist == NULL || addr == NULL) return EXPR_ERROR_NULLPOINTER; if(name == NULL || name[0] == '\0') return EXPR_ERROR_NOTFOUND; /* Search for the item */ cur = vlist->head; while(cur) { result = strcmp(name, cur->vname); if(result == 0) { /* We found it. */ if(cur->vptr) *addr = cur->vptr; else *addr = &(cur->vval); /* return now */ return EXPR_ERROR_NOERROR; } cur = cur->next; } /* If we got here, we did not find it in the list */ return EXPR_ERROR_NOTFOUND; } /* This function is used to enumerate the values in a value list */ void *exprValListGetNext(exprValList *vlist, char **name, EXPRTYPE *value, EXPRTYPE** addr, void *cookie) { exprVal *cur; if(vlist == NULL) return NULL; /* Get the current item */ cur = (exprVal*)cookie; /* Find the next item */ if(cur == NULL) cur = vlist->head; else cur = cur->next; /* Set up the data */ if(cur) { if(name) *name = cur->vname; if(value) { if(cur->vptr) *value = *(cur->vptr); else *value = cur->vval; } if(addr) { if(cur->vptr) *addr = cur->vptr; else *addr = &(cur->vval); } } /* If there was no value, return NULL, otherwise, return the item */ return (void*)cur; } /* This routine will free the value list */ int exprValListFree(exprValList *vlist) { /* Make sure it exists, if not it is not error */ if(vlist == NULL) return EXPR_ERROR_NOERROR; /* Free the nodes */ exprValListFreeData(vlist->head); /* Freethe container */ exprFreeMem(vlist); return EXPR_ERROR_NOERROR; } /* This routine will reset the value list to 0.0 */ int exprValListClear(exprValList *vlist) { if(vlist == NULL) return EXPR_ERROR_NOERROR; exprValListResetData(vlist->head); return EXPR_ERROR_NOERROR; } /* This routine will free any child nodes, and then free itself */ static void exprValListFreeData(exprVal *val) { exprVal *next; while(val) { /* Remember the next */ next = val->next; /* Free name */ exprFreeMem(val->vname); /* Free ourself */ exprFreeMem(val); val = next; } } /* This routine will reset variables to 0.0 */ static void exprValListResetData(exprVal *val) { while(val) { /* Reset data */ if(val->vptr) *(val->vptr) = 0.0; val->vval = 0.0; val = val->next; } } /* This routine will create the value object */ static exprVal *exprCreateVal(char *name, EXPRTYPE val, EXPRTYPE *addr) { exprVal *tmp; char *vtmp; /* Name already tested in exprValListAdd */ /* Create it */ tmp = exprAllocMem(sizeof(exprVal)); if(tmp == NULL) return NULL; /* Allocate space for the name */ vtmp = exprAllocMem(strlen(name) + 1); if(vtmp == NULL) { exprFreeMem(tmp); return NULL; } /* Copy the data over */ strcpy(vtmp, name); tmp->vname = vtmp; tmp->vval = val; tmp->vptr = addr; return tmp; }