/* 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; }