| /****************************************************************************** |
| * Copyright (c) 2005 The Regents of the University of California. |
| * This material was produced under U.S. Government contract W-7405-ENG-36 |
| * for Los Alamos National Laboratory, which is operated by the University |
| * of California for the U.S. Department of Energy. The U.S. Government has |
| * rights to use, reproduce, and distribute this software. NEITHER THE |
| * GOVERNMENT NOR THE UNIVERSITY MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR |
| * ASSUMES ANY LIABILITY FOR THE USE OF THIS SOFTWARE. If software is modified |
| * to produce derivative works, such modified software should be clearly |
| * marked, so as not to confuse it with the version available from LANL. |
| * |
| * Additionally, this program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * LA-CC 04-115 |
| ******************************************************************************/ |
| |
| /* |
| * Based on the QNX Java implementation of the MI interface |
| */ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include "list.h" |
| #include "MIValue.h" |
| #include "MIResult.h" |
| #include "MIVar.h" |
| #include "MIOOBRecord.h" |
| |
| MIVar * |
| MIVarNew(void) |
| { |
| MIVar * var = (MIVar *)malloc(sizeof(MIVar)); |
| var->name = NULL; |
| var->type = NULL; |
| var->exp = NULL; |
| var->numchild = 0; |
| var->children = NULL; |
| return var; |
| } |
| |
| void |
| MIVarFree(MIVar *var) |
| { |
| int i; |
| |
| if (var->name != NULL) |
| free(var->name); |
| if (var->type != NULL) |
| free(var->type); |
| if (var->exp != NULL) |
| free(var->exp); |
| if (var->children != NULL) { |
| for (i = 0; i < var->numchild; i++) |
| MIVarFree(var->children[i]); |
| free(var->children); |
| } |
| free(var); |
| } |
| |
| MIVarChange * |
| MIVarChangeNew(void) { |
| MIVarChange *varchange = (MIVarChange *)malloc(sizeof(MIVarChange)); |
| |
| varchange->name = NULL; |
| varchange->in_scope = 0; |
| varchange->type_changed = 0; |
| return varchange; |
| } |
| |
| void |
| MIVarChangeFree(MIVarChange *varchange) { |
| if (varchange->name != NULL) |
| free(varchange->name); |
| free(varchange); |
| } |
| |
| MIVar * |
| MIVarParse(List *results) |
| { |
| MIValue * value; |
| MIResult * result; |
| MIVar * var = MIVarNew(); |
| char * str; |
| |
| for (SetList(results); (result = (MIResult *)GetListElement(results)) != NULL; ) { |
| value = result->value; |
| if (value != NULL && value->type == MIValueTypeConst) { |
| str = value->cstring; |
| } else { |
| str = ""; |
| } |
| |
| if (strcmp(result->variable, "numchild") == 0) { |
| var->numchild = (int)strtol(str, NULL, 10); |
| } else if (strcmp(result->variable, "name") == 0) { |
| var->name = strdup(str); |
| } else if (strcmp(result->variable, "type") == 0) { |
| var->type = strdup(str); |
| } else if (strcmp(result->variable, "exp") == 0) { |
| var->exp = strdup(str); |
| } |
| } |
| |
| return var; |
| } |
| |
| MIVar * |
| MIGetVarCreateInfo(MICommand *cmd) |
| { |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return NULL; |
| |
| return MIVarParse(cmd->output->rr->results); |
| } |
| |
| /* |
| * Some gdb MacOSX do not return a MITuple so we have |
| * to check for different format. |
| * See PR 81019 |
| */ |
| void |
| parseChildren(MIValue *val, List **res) |
| { |
| MIValue * value; |
| MIResult * result; |
| List * children = NULL; |
| List * results = val->results; |
| |
| if (results != NULL) { |
| for (SetList(results); (result = (MIResult *)GetListElement(results)) != NULL; ) { |
| if (strcmp(result->variable, "child") == 0) { //$NON-NLS-1$ |
| value = result->value; |
| if (value->type == MIValueTypeTuple) { |
| if (children == NULL) |
| children = NewList(); |
| AddToList(children, MIVarParse(value->results)); |
| } |
| } |
| } |
| } |
| *res = children; |
| } |
| |
| void |
| MIGetVarListChildrenInfo(MIVar *var, MICommand *cmd) |
| { |
| int num; |
| MIVar * child; |
| MIValue * value; |
| MIResult * result; |
| MIResultRecord * rr; |
| List * children = NULL; |
| |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return; |
| |
| rr = cmd->output->rr; |
| for (SetList(rr->results); (result = (MIResult *)GetListElement(rr->results)) != NULL; ) { |
| value = result->value; |
| |
| if (strcmp(result->variable, "numchild") == 0) { |
| if (value->type == MIValueTypeConst) { |
| var->numchild = (int)strtol(value->cstring, NULL, 10); |
| } |
| } else if (strcmp(result->variable, "children") == 0) { |
| parseChildren(value, &children); |
| } |
| } |
| |
| if (children != NULL) { |
| num = SizeOfList(children); |
| if (var->numchild != num) |
| var->numchild = num; |
| var->children = (MIVar **)malloc(sizeof(MIVar *) * var->numchild); |
| for (num = 0, SetList(children); (child = (MIVar *)GetListElement(children)) != NULL; ) |
| var->children[num++] = child; |
| } |
| } |
| |
| char * |
| MIGetVarEvaluateExpressionInfo(MICommand *cmd) |
| { |
| MIValue * value; |
| MIResult * result; |
| MIResultRecord * rr; |
| char * expr = NULL; |
| |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return NULL; |
| |
| rr = cmd->output->rr; |
| for (SetList(rr->results); (result = (MIResult *)GetListElement(rr->results)) != NULL; ) { |
| value = result->value; |
| if (strcmp(result->variable, "value") == 0) { |
| if (value->type == MIValueTypeConst) { |
| expr = strdup(value->cstring); |
| } |
| } |
| } |
| return expr; |
| } |
| |
| char * |
| MIGetDataEvaluateExpressionInfo(MICommand *cmd) |
| { |
| MIValue * value; |
| MIResult * result; |
| MIResultRecord * rr; |
| char * expr = NULL; |
| |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return NULL; |
| |
| rr = cmd->output->rr; |
| for (SetList(rr->results); (result = (MIResult *)GetListElement(rr->results)) != NULL; ) { |
| value = result->value; |
| if (strcmp(result->variable, "value") == 0) { |
| if (value->type == MIValueTypeConst) { |
| expr = strdup(value->cstring); |
| } |
| } |
| } |
| return expr; |
| } |
| |
| void |
| MIGetVarUpdateParseValue(MIValue* tuple, List* varchanges) |
| { |
| MIResult * result; |
| char * str = NULL; |
| char * var; |
| MIValue * value; |
| MIVarChange * varchange = NULL; |
| List * results = tuple->results; |
| |
| if (results != NULL) { |
| for (SetList(results); (result = (MIResult *)GetListElement(results)) != NULL;) { |
| var = result->variable; |
| value = result->value; |
| |
| //this code is for mac |
| if (value->type == MIValueTypeTuple) { |
| MIGetVarUpdateParseValue(value, varchanges); |
| continue; |
| } |
| |
| if (value->type == MIValueTypeConst) { |
| str = value->cstring; |
| } |
| |
| if (strcmp(var, "name") == 0 && str != NULL) { |
| varchange = MIVarChangeNew(); |
| varchange->name = strdup(str); |
| AddToList(varchanges, (void *)varchange); |
| } else if (strcmp(var, "in_scope") == 0) { |
| if (varchange != NULL) { |
| varchange->in_scope = (strcmp(str, "true")==0)?1:0; |
| } |
| } else if (strcmp(var, "type_changed") == 0) { |
| if (varchange != NULL) { |
| varchange->type_changed = (strcmp(str, "true")==0)?1:0; |
| } |
| } |
| } |
| } |
| } |
| |
| void |
| MIGetVarUpdateParser(MIValue* miVal, List *varchanges) |
| { |
| MIValue* value; |
| MIResult* result; |
| |
| if (miVal->type == MIValueTypeTuple) { |
| MIGetVarUpdateParseValue(miVal, varchanges); |
| } |
| else if (miVal->type == MIValueTypeList) { |
| if (EmptyList(miVal->values)) { |
| for (SetList(miVal->results); (result = (MIResult *)GetListElement(miVal->results)) != NULL;) { |
| MIGetVarUpdateParser(result->value, varchanges); |
| } |
| } |
| else { |
| for (SetList(miVal->values); (value = (MIValue *)GetListElement(miVal->values)) != NULL;) { |
| MIGetVarUpdateParser(value, varchanges); |
| } |
| } |
| } |
| } |
| |
| void |
| MIGetVarUpdateInfo(MICommand *cmd, List** varchanges) |
| { |
| MIResult * result; |
| MIResultRecord * rr; |
| *varchanges = NewList(); |
| |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return; |
| |
| rr = cmd->output->rr; |
| for (SetList(rr->results); (result = (MIResult *)GetListElement(rr->results)) != NULL;) { |
| if (strcmp(result->variable, "changelist") == 0) { |
| MIGetVarUpdateParser(result->value, *varchanges); |
| } |
| } |
| } |
| |
| MIVar * |
| MIGetVarInfoType(MICommand *cmd) |
| { |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return NULL; |
| |
| return MIVarParse(cmd->output->rr->results); |
| } |
| |
| void |
| MIGetVarInfoNumChildren(MICommand *cmd, MIVar *var) |
| { |
| if (!cmd->completed || cmd->output == NULL || cmd->output->rr == NULL) |
| return; |
| |
| List *results; |
| MIValue * value; |
| MIResult * result; |
| char * str; |
| |
| if (var == NULL) |
| var = MIVarNew(); |
| |
| results = cmd->output->rr->results; |
| for (SetList(results); (result = (MIResult *)GetListElement(results)) != NULL; ) { |
| value = result->value; |
| if (value != NULL && value->type == MIValueTypeConst) { |
| str = value->cstring; |
| } else { |
| str = ""; |
| } |
| |
| if (strcmp(result->variable, "numchild") == 0) { |
| var->numchild = (int)strtol(str, NULL, 10); |
| } |
| } |
| } |