blob: 69c1c1da80d350c99cd0a0c74458a249760ded2a [file] [log] [blame]
/******************************************************************************
* 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);
}
}
}