/*\ * libLB - The LBPP support library * Copyright (C) 2001 Anthony Liguori * * libLB is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * libLB is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*/ #include #include #include #include #include #include #include #include "lb.h" void lb_init_cxt(LBContext *cxt, int argc, char **argv, int num_vars, int num_labels, char *source) { time_t t = time(0); srandom(t); cxt->vars_size = 0; cxt->vars_capacity = num_vars; cxt->vars = (Variable *)malloc(cxt->vars_capacity * sizeof(Variable)); cxt->labels_size = 0; cxt->labels_capacity = num_labels; cxt->labels = (Label *)malloc(cxt->labels_capacity * sizeof(Label)); cxt->jmps_size = 0; cxt->jmps_capacity = 20; cxt->jmps = (jmp_buf *)malloc(cxt->jmps_capacity * sizeof(jmp_buf)); cxt->devs_size = 0; cxt->devs_capacity = 10; cxt->devs = (LBDevice *)malloc(cxt->devs_capacity * sizeof(LBDevice)); cxt->dev_class_size = 0; cxt->dev_class_capacity = 10; cxt->dev_class = (LBDeviceClass *)malloc(cxt->dev_class_capacity * sizeof(LBDeviceClass)); cxt->source = source; } void lb_push_label(LBContext *cxt, jmp_buf *jmp) { int i = cxt->jmps_size; if (++(cxt->jmps_size) > cxt->jmps_capacity) { cxt->jmps_capacity += 10; cxt->jmps = (jmp_buf *)realloc(cxt->jmps, cxt->jmps_capacity * sizeof(jmp_buf)); } memcpy(&(cxt->jmps[i]), jmp, sizeof(jmp_buf)); } void lb_pop_label(LBContext *cxt, jmp_buf *jmp) { assert(cxt->jmps_size); memcpy(jmp, &(cxt->jmps[--(cxt->jmps_size)]), sizeof(jmp_buf)); } int lb_add_var(LBContext *cxt, char *name, Type type, int rows, int columns) { int i = cxt->vars_size; LBString empty_str = lbstr_cstr(""); if (++(cxt->vars_size) > cxt->vars_capacity) { cxt->vars_capacity += 10; cxt->vars = (Variable *)realloc(cxt->vars, cxt->vars_capacity * sizeof(Variable)); } cxt->vars[i].type = type; cxt->vars[i].name = lbstr_str(name); cxt->vars[i].rows = rows; cxt->vars[i].columns = columns; if ((rows == 1) && (columns == 1)) { switch(type) { case DOUBLE: cxt->vars[i].data.db = 0; break; case STRING: cxt->vars[i].data.str = lbstr_dup(empty_str); break; case HANDLE: cxt->vars[i].data.hnd.dev = 0; cxt->vars[i].data.hnd.data = 0; break; default: break; } } else { int j, k; switch(type) { case DOUBLE: cxt->vars[i].data.db_v = (double *)malloc(rows * columns * sizeof(double)); for (j = 0; j < rows; j++) { for (k = 0; k < columns; k++) { cxt->vars[i].data.db_v[(k * columns) + j] = 0; } } break; case STRING: cxt->vars[i].data.str_v = (LBString *)malloc(rows * columns * sizeof(LBString)); for (j = 0; j < rows; j++) { for (k = 0; k < columns; k++) { cxt->vars[i].data.str_v[(k * columns) + j] = lbstr_dup(empty_str); } } break; case HANDLE: cxt->vars[i].data.hnd_v = (LBHandle *)malloc(rows * columns * sizeof(LBHandle)); for (j = 0; j < rows; j++) { for (k = 0; k < columns; k++) { cxt->vars[i].data.hnd_v[(k * columns) + j].dev = 0; cxt->vars[i].data.hnd_v[(k * columns) + j].data = 0; } } break; default: break; } } lbstr_destroy(empty_str); return i; } int lb_add_label(LBContext *cxt, char *name) { int i = cxt->labels_size; if (++(cxt->labels_size) > cxt->labels_capacity) { cxt->labels_capacity += 10; cxt->labels = (Label *)realloc(cxt->labels, cxt->labels_capacity * sizeof(Label)); } cxt->labels[i].name = lbstr_str(name); return i; } void lb_free_cxt(LBContext *cxt) { int i; for (i = 0; i < cxt->vars_size; i++) { switch(cxt->vars[i].type) { case STRING: if ((cxt->vars[i].rows > 1) || (cxt->vars[i].columns > 1)) { int j; for (j = 0; j < (cxt->vars[i].rows * cxt->vars[i].columns); j++) { lbstr_destroy(cxt->vars[i].data.str_v[j]); } free(cxt->vars[i].data.str_v); } else { lbstr_destroy(cxt->vars[i].data.str); } break; case DOUBLE: if ((cxt->vars[i].rows > 1) || (cxt->vars[i].columns > 1)) { free(cxt->vars[i].data.db_v); } break; case HANDLE: if ((cxt->vars[i].rows > 1) || (cxt->vars[i].columns > 1)) { free(cxt->vars[i].data.hnd_v); } break; default: break; } } free(cxt->vars); cxt->vars = 0; cxt->vars_size = 0; cxt->vars_capacity = 0; for (i = 0; i < cxt->labels_size; i++) { lbstr_destroy(cxt->labels[i].name); } free(cxt->labels); cxt->labels = 0; cxt->labels_size = 0; cxt->labels_capacity = 0; free(cxt->devs); cxt->devs = 0; cxt->devs_size = 0; cxt->devs_capacity = 0; free(cxt->dev_class); cxt->dev_class = 0; cxt->dev_class_size = 0; cxt->dev_class_capacity = 0; free(cxt->jmps); cxt->jmps = 0; cxt->jmps_size = 0; cxt->jmps_capacity = 0; } LBVarArg *lb_va_adds(LBString str, LBVarArg *list) { LBVarArg *node = malloc(sizeof(LBVarArg)); node->reference = 0; node->type.var_type = STRING; node->data.str = str; node->next = list; return node; } LBVarArg *lb_va_addd(double d, LBVarArg *list) { LBVarArg *node = malloc(sizeof(LBVarArg)); node->reference = 0; node->type.var_type = DOUBLE; node->data.db = d; node->next = list; return node; } LBVarArg *lb_va_addv(Variable *var, LBVarArg *list) { LBVarArg *node = malloc(sizeof(LBVarArg)); node->reference = 1; node->type.var_type = var->type; node->data.var = var; node->next = list; return node; } LBVarArg *lb_va_end(LBVarArgEnd type) { LBVarArg *node = malloc(sizeof(LBVarArg)); node->reference = 0; node->type.end_type = type; node->next = 0; return node; } void lb_va_destroy(LBVarArg *list) { LBVarArg *node = list; while (node->next) { LBVarArg *temp = node; node = node->next; if (temp->type.var_type == STRING) { lbstr_destroy(temp->data.str); } free(temp); } free(node); } Variable *lb_lookup_var(LBContext *cxt, char *name) { int i; for (i = 0; i < cxt->vars_size; i++) { if (!strcmp(cxt->vars[i].name->data, name)) { return &(cxt->vars[i]); } } return 0; } Label *lb_lookup_label(LBContext *cxt, char *name) { int i; for (i = 0; i < cxt->labels_size; i++) { if (!strcmp(cxt->labels[i].name->data, name)) { return &(cxt->labels[i]); } } return 0; }