1 /**[txh]********************************************************************
3 Copyright (c) 2004-2007 by Salvador E. Tropea.
4 Covered by the GPL license.
8 Parses the output of gdb. It basically converts the text from gdb into a
9 tree (could be a complex one) that we can easily interpret using C code.
11 ***************************************************************************/
18 mi_results *mi_get_result(const char *str, const char **end);
19 int mi_get_value(mi_results *r, const char *str, const char **end);
23 ^error,msg="Problem parsing arguments: data-evaluate-expression ""1+2"""
24 Afects gdb 2002-04-01-cvs and 6.1.1 for sure.
25 That's an heuristical workaround.
28 int EndOfStr(const char *s)
33 return !*s || *s==',' || *s==']' || *s=='}';
38 int mi_get_cstring_r(mi_results *r, const char *str, const char **end)
51 for (s=str, len=0; *s && !EndOfStr(s); s++)
63 d=r->v.cstr=mi_malloc(len+1);
66 for (s=str; *s && !EndOfStr(s); s++, d++)
93 /* TODO: What's a valid variable name?
94 I'll assume a-zA-Z0-9_- */
96 int mi_is_var_name_char(char c)
98 return isalnum(c) || c=='-' || c=='_';
101 char *mi_get_var_name(const char *str, const char **end)
107 for (s=str; *s && mi_is_var_name_char(*s); s++);
127 int mi_get_list_res(mi_results *r, const char *str, const char **end, char closeC)
129 mi_results *last_r, *rs;
134 rs=mi_get_result(str,&str);
156 int mi_get_tuple_val(mi_results *r, const char *str, const char **end)
158 mi_results *last_r, *rs;
163 rs=mi_alloc_results();
164 if (!rs || !mi_get_value(rs,str,&str))
169 /* Note that rs->var is NULL, that indicates that's just a value and not
190 #endif /* __APPLE__ */
192 int mi_get_tuple(mi_results *r, const char *str, const char **end)
202 {/* Special case: empty tuple */
207 if (mi_is_var_name_char(*str))
208 return mi_get_list_res(r,str,end,'}');
209 return mi_get_tuple_val(r,str,end);
210 #else /* __APPLE__ */
211 return mi_get_list_res(r,str,end,'}');
212 #endif /* __APPLE__ */
215 int mi_get_list_val(mi_results *r, const char *str, const char **end)
217 mi_results *last_r, *rs;
222 rs=mi_alloc_results();
223 if (!rs || !mi_get_value(rs,str,&str))
228 /* Note that rs->var is NULL, that indicates that's just a value and not
250 int mi_get_list(mi_results *r, const char *str, const char **end)
260 {/* Special case: empty list */
264 /* Comment: I think they could choose () for values. Is confusing in this way. */
265 if (mi_is_var_name_char(*str))
266 return mi_get_list_res(r,str,end,']');
267 return mi_get_list_val(r,str,end);
270 int mi_get_value(mi_results *r, const char *str, const char **end)
275 return mi_get_cstring_r(r,str,end);
277 return mi_get_tuple(r,str,end);
279 return mi_get_list(r,str,end);
285 mi_results *mi_get_result(const char *str, const char **end)
290 var=mi_get_var_name(str,&str);
294 r=mi_alloc_results();
302 if (!mi_get_value(r,str,end))
311 mi_output *mi_get_results_alone(mi_output *r,const char *str)
313 mi_results *last_r, *rs;
327 rs=mi_get_result(str,&str);
341 mi_output *mi_parse_result_record(mi_output *r,const char *str)
343 r->type=MI_T_RESULT_RECORD;
345 /* Solve the result-class. */
346 if (strncmp(str,"done",4)==0)
349 r->tclass=MI_CL_DONE;
351 else if (strncmp(str,"running",7)==0)
354 r->tclass=MI_CL_RUNNING;
356 else if (strncmp(str,"connected",9)==0)
359 r->tclass=MI_CL_CONNECTED;
361 else if (strncmp(str,"error",5)==0)
364 r->tclass=MI_CL_ERROR;
366 else if (strncmp(str,"exit",4)==0)
369 r->tclass=MI_CL_EXIT;
373 mi_error=MI_UNKNOWN_RESULT;
377 return mi_get_results_alone(r,str);
380 mi_output *mi_parse_asyn(mi_output *r,const char *str)
382 r->type=MI_T_OUT_OF_BAND;
383 r->stype=MI_ST_ASYNC;
385 if (strncmp(str,"stopped",7)==0)
387 r->tclass=MI_CL_STOPPED;
389 return mi_get_results_alone(r,str);
391 if (strncmp(str,"download",8)==0)
393 r->tclass=MI_CL_DOWNLOAD;
395 return mi_get_results_alone(r,str);
397 mi_error=MI_UNKNOWN_ASYNC;
402 mi_output *mi_parse_exec_asyn(mi_output *r,const char *str)
404 r->sstype=MI_SST_EXEC;
405 return mi_parse_asyn(r,str);
408 mi_output *mi_parse_status_asyn(mi_output *r,const char *str)
410 r->sstype=MI_SST_STATUS;
411 return mi_parse_asyn(r,str);
414 mi_output *mi_parse_notify_asyn(mi_output *r,const char *str)
416 r->sstype=MI_SST_NOTIFY;
417 return mi_parse_asyn(r,str);
420 mi_output *mi_console(mi_output *r,const char *str)
422 r->type=MI_T_OUT_OF_BAND;
423 r->stype=MI_ST_STREAM;
424 r->c=mi_alloc_results();
425 if (!r->c || !mi_get_cstring_r(r->c,str,NULL))
433 mi_output *mi_console_stream(mi_output *r,const char *str)
435 r->sstype=MI_SST_CONSOLE;
436 return mi_console(r,str);
439 mi_output *mi_target_stream(mi_output *r,const char *str)
441 r->sstype=MI_SST_TARGET;
442 return mi_console(r,str);
445 mi_output *mi_log_stream(mi_output *r,const char *str)
447 r->sstype=MI_SST_LOG;
448 return mi_console(r,str);
451 mi_output *mi_parse_gdb_output(const char *str)
455 mi_output *r=mi_alloc_output();
458 mi_error=MI_OUT_OF_MEMORY;
465 return mi_parse_result_record(r,str);
467 return mi_parse_exec_asyn(r,str);
469 return mi_parse_status_asyn(r,str);
471 return mi_parse_notify_asyn(r,str);
473 return mi_console_stream(r,str);
475 return mi_target_stream(r,str);
477 return mi_log_stream(r,str);
483 mi_output *mi_get_rrecord(mi_output *r)
489 if (r->type==MI_T_RESULT_RECORD)
496 mi_results *mi_get_var_r(mi_results *r, const char *var)
500 if (strcmp(r->var,var)==0)
507 mi_results *mi_get_var(mi_output *res, const char *var)
511 return mi_get_var_r(res->c,var);
514 int mi_get_async_stop_reason(mi_output *r, char **reason)
521 if (r->type==MI_T_RESULT_RECORD && r->tclass==MI_CL_ERROR)
523 if (r->c->type==t_const)
524 *reason=r->c->v.cstr;
527 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
528 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
534 if (strcmp(p->var,"reason")==0)
544 if (*reason==NULL && found_stopped)
546 *reason=strdup("unknown (temp bkpt?)");
552 mi_frames *mi_get_async_frame(mi_output *r)
556 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
557 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
562 if (strcmp(p->var,"frame")==0)
563 return mi_parse_frame(p->v.rs);
572 int mi_res_simple(mi_h *h, int tclass, int accert_ret)
577 r=mi_get_response_blk(h);
578 res=mi_get_rrecord(r);
581 ret=res->tclass==tclass;
588 int mi_res_simple_done(mi_h *h)
590 return mi_res_simple(h,MI_CL_DONE,0);
593 int mi_res_simple_exit(mi_h *h)
595 return mi_res_simple(h,MI_CL_EXIT,1);
598 int mi_res_simple_running(mi_h *h)
600 return mi_res_simple(h,MI_CL_RUNNING,0);
603 int mi_res_simple_connected(mi_h *h)
605 return mi_res_simple(h,MI_CL_CONNECTED,0);
608 mi_results *mi_res_var(mi_h *h, const char *var, int tclass)
611 mi_results *the_var=NULL;
613 r=mi_get_response_blk(h);
614 /* All the code that follows is "NULL" tolerant. */
615 /* Look for the result-record. */
616 res=mi_get_rrecord(r);
617 /* Look for the desired var. */
618 if (res && res->tclass==tclass)
619 the_var=mi_get_var(res,var);
620 /* Release all but the one we want. */
621 mi_free_output_but(r,NULL,the_var);
625 mi_results *mi_res_done_var(mi_h *h, const char *var)
627 return mi_res_var(h,var,MI_CL_DONE);
630 mi_frames *mi_parse_frame(mi_results *c)
632 mi_frames *res=mi_alloc_frames();
639 if (c->type==t_const)
641 if (strcmp(c->var,"level")==0)
642 res->level=atoi(c->v.cstr);
643 else if (strcmp(c->var,"addr")==0)
644 res->addr=(void *)strtoul(c->v.cstr,&end,0);
645 else if (strcmp(c->var,"func")==0)
650 else if (strcmp(c->var,"file")==0)
655 else if (strcmp(c->var,"from")==0)
660 else if (strcmp(c->var,"line")==0)
661 res->line=atoi(c->v.cstr);
663 else if (c->type==t_list && strcmp(c->var,"args")==0)
674 mi_frames *mi_res_frame(mi_h *h)
676 mi_results *r=mi_res_done_var(h,"frame");
679 if (r && r->type==t_tuple)
680 f=mi_parse_frame(r->v.rs);
685 mi_frames *mi_res_frames_array(mi_h *h, const char *var)
687 mi_results *r=mi_res_done_var(h,var), *c;
688 mi_frames *res=NULL, *nframe, *last=NULL;
693 if (r->type!=t_list && r->type!=t_tuple)
704 if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
706 nframe=mi_parse_frame(c->v.rs);
722 mi_frames *mi_res_frames_list(mi_h *h)
725 mi_frames *ret=NULL, *nframe, *last=NULL;
728 r=mi_get_response_blk(h);
729 res=mi_get_rrecord(r);
730 if (res && res->tclass==MI_CL_DONE)
735 if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
737 nframe=mi_parse_frame(c->v.rs);
754 int mi_get_thread_ids(mi_output *res, int **list)
756 mi_results *vids, *lids;
760 vids=mi_get_var(res,"number-of-threads");
761 lids=mi_get_var(res,"thread-ids");
762 if (vids && vids->type==t_const &&
763 lids && lids->type==t_tuple)
765 ids=atoi(vids->v.cstr);
769 lst=(int *)mi_calloc(ids,sizeof(int));
776 if (strcmp(lids->var,"thread-id")==0 && lids->type==t_const)
777 lst[i++]=atoi(lids->v.cstr);
789 int mi_res_thread_ids(mi_h *h, int **list)
794 r=mi_get_response_blk(h);
795 res=mi_get_rrecord(r);
796 if (res && res->tclass==MI_CL_DONE)
797 ids=mi_get_thread_ids(res,list);
802 enum mi_gvar_lang mi_lang_str_to_enum(const char *lang)
804 enum mi_gvar_lang lg=lg_unknown;
806 if (strcmp(lang,"C")==0)
808 else if (strcmp(lang,"C++")==0)
810 else if (strcmp(lang,"Java")==0)
816 const char *mi_lang_enum_to_str(enum mi_gvar_lang lang)
839 enum mi_gvar_fmt mi_format_str_to_enum(const char *format)
841 enum mi_gvar_fmt fmt=fm_natural;
843 if (strcmp(format,"binary")==0)
845 else if (strcmp(format,"decimal")==0)
847 else if (strcmp(format,"hexadecimal")==0)
849 else if (strcmp(format,"octal")==0)
855 const char *mi_format_enum_to_str(enum mi_gvar_fmt format)
885 char mi_format_enum_to_char(enum mi_gvar_fmt format)
915 mi_gvar *mi_get_gvar(mi_output *o, mi_gvar *cur, const char *expression)
918 mi_gvar *res=cur ? cur : mi_alloc_gvar();
925 res->exp=strdup(expression);
928 if (r->type==t_const)
930 if (strcmp(r->var,"name")==0)
936 else if (strcmp(r->var,"numchild")==0)
938 res->numchild=atoi(r->v.cstr);
940 else if (strcmp(r->var,"type")==0)
946 if (l && res->type[l-1]=='*')
949 else if (strcmp(r->var,"lang")==0)
951 res->lang=mi_lang_str_to_enum(r->v.cstr);
953 else if (strcmp(r->var,"exp")==0)
959 else if (strcmp(r->var,"format")==0)
961 res->format=mi_format_str_to_enum(r->v.cstr);
963 else if (strcmp(r->var,"attr")==0)
964 { /* Note: gdb 6.1.1 have only this: */
965 if (strcmp(r->v.cstr,"editable")==0)
966 res->attr=MI_ATTR_EDITABLE;
967 else /* noneditable */
968 res->attr=MI_ATTR_NONEDITABLE;
976 mi_gvar *mi_res_gvar(mi_h *h, mi_gvar *cur, const char *expression)
981 r=mi_get_response_blk(h);
982 res=mi_get_rrecord(r);
983 if (res && res->tclass==MI_CL_DONE)
984 gvar=mi_get_gvar(res,cur,expression);
989 mi_gvar_chg *mi_get_gvar_chg(mi_results *r)
993 if (r->type!=t_const)
995 n=mi_alloc_gvar_chg();
1000 if (r->type==t_const)
1002 if (strcmp(r->var,"name")==0)
1007 else if (strcmp(r->var,"in_scope")==0)
1009 n->in_scope=strcmp(r->v.cstr,"true")==0;
1011 else if (strcmp(r->var,"new_type")==0)
1013 n->new_type=r->v.cstr;
1016 else if (strcmp(r->var,"new_num_children")==0)
1018 n->new_num_children=atoi(r->v.cstr);
1020 // type_changed="false" is the default
1028 int mi_res_changelist(mi_h *h, mi_gvar_chg **changed)
1030 mi_gvar_chg *last, *n;
1031 mi_results *res=mi_res_done_var(h,"changelist"), *r;
1042 if (res->type==t_list)
1043 {// MI v2 a list of tuples
1046 if (r->type==t_tuple)
1048 n=mi_get_gvar_chg(r->v.rs);
1062 else if (res->type==t_tuple)
1063 {// MI v1 a tuple with all together *8-P
1066 if (r->type==t_const) /* Just in case. */
1068 if (strcmp(r->var,"name")==0)
1071 {/* Add to the list*/
1079 n=mi_alloc_gvar_chg();
1082 mi_free_gvar_chg(*changed);
1088 else if ((NULL != n) && (strcmp(r->var,"in_scope")==0))
1090 n->in_scope=strcmp(r->v.cstr,"true")==0;
1092 else if ((NULL != n) && (strcmp(r->var,"new_type")==0))
1094 n->new_type=r->v.cstr;
1097 else if ((NULL != n) && (strcmp(r->var,"new_num_children")==0))
1099 n->new_num_children=atoi(r->v.cstr);
1101 // type_changed="false" is the default
1106 {/* Add to the list*/
1115 mi_free_results(res);
1120 int mi_get_children(mi_results *ch, mi_gvar *v)
1122 mi_gvar *cur=NULL, *aux;
1123 int i=0, count=v->numchild, l;
1127 if (strcmp(ch->var,"child")==0 && ch->type==t_tuple && i<count)
1129 mi_results *r=ch->v.rs;
1130 aux=mi_alloc_gvar();
1135 else if (NULL != cur)
1139 cur->depth=v->depth+1;
1143 if (r->type==t_const)
1145 if (strcmp(r->var,"name")==0)
1147 cur->name=r->v.cstr;
1150 else if (strcmp(r->var,"exp")==0)
1155 else if (strcmp(r->var,"type")==0)
1157 cur->type=r->v.cstr;
1159 l=strlen(cur->type);
1160 if (l && cur->type[l-1]=='*')
1163 else if (strcmp(r->var,"value")==0)
1165 cur->value=r->v.cstr;
1168 else if (strcmp(r->var,"numchild")==0)
1170 cur->numchild=atoi(r->v.cstr);
1181 return i==v->numchild;
1184 int mi_res_children(mi_h *h, mi_gvar *v)
1189 r=mi_get_response_blk(h);
1190 res=mi_get_rrecord(r);
1191 if (res && res->tclass==MI_CL_DONE)
1193 mi_results *num=mi_get_var(res,"numchild");
1194 if (num && num->type==t_const)
1196 v->numchild=atoi(num->v.cstr);
1199 mi_free_gvar(v->child);
1204 mi_results *ch =mi_get_var(res,"children");
1205 if (ch && ch->type!=t_const) /* MI v1 tuple, MI v2 list */
1206 ok=mi_get_children(ch->v.rs,v);
1216 mi_bkpt *mi_get_bkpt(mi_results *p)
1221 res=mi_alloc_bkpt();
1226 if (p->type==t_const && p->var)
1228 if (strcmp(p->var,"number")==0)
1229 res->number=atoi(p->v.cstr);
1230 else if (strcmp(p->var,"type")==0)
1232 if (strcmp(p->v.cstr,"breakpoint")==0)
1233 res->type=t_breakpoint;
1235 res->type=t_unknown;
1237 else if (strcmp(p->var,"disp")==0)
1239 if (strcmp(p->v.cstr,"keep")==0)
1241 else if (strcmp(p->v.cstr,"del")==0)
1244 res->disp=d_unknown;
1246 else if (strcmp(p->var,"enabled")==0)
1247 res->enabled=p->v.cstr[0]=='y';
1248 else if (strcmp(p->var,"addr")==0)
1249 res->addr=(void *)strtoul(p->v.cstr,&end,0);
1250 else if (strcmp(p->var,"func")==0)
1252 res->func=p->v.cstr;
1255 else if (strcmp(p->var,"file")==0)
1257 res->file=p->v.cstr;
1260 else if (strcmp(p->var,"line")==0)
1261 res->line=atoi(p->v.cstr);
1262 else if (strcmp(p->var,"times")==0)
1263 res->times=atoi(p->v.cstr);
1264 else if (strcmp(p->var,"ignore")==0)
1265 res->ignore=atoi(p->v.cstr);
1266 else if (strcmp(p->var,"cond")==0)
1268 res->cond=p->v.cstr;
1277 mi_bkpt *mi_res_bkpt(mi_h *h)
1279 mi_results *r=mi_res_done_var(h,"bkpt");
1282 if (r && r->type==t_tuple)
1283 b=mi_get_bkpt(r->v.rs);
1288 mi_wp *mi_get_wp(mi_results *p, enum mi_wp_mode m)
1290 mi_wp *res=mi_alloc_wp();
1297 if (p->type==t_const && p->var)
1299 if (strcmp(p->var,"number")==0)
1301 res->number=atoi(p->v.cstr);
1304 else if (strcmp(p->var,"exp")==0)
1316 mi_wp *mi_parse_wp_res(mi_output *r)
1319 enum mi_wp_mode m=wm_unknown;
1321 /* The info is in a result wpt=... */
1327 if (strcmp(p->var,"wpt")==0)
1329 else if (strcmp(p->var,"hw-rwpt")==0)
1331 else if (strcmp(p->var,"hw-awpt")==0)
1338 if (!p || p->type!=t_tuple)
1340 /* Scan the values inside it. */
1341 return mi_get_wp(p->v.rs,m);
1344 mi_wp *mi_res_wp(mi_h *h)
1349 r=mi_get_response_blk(h);
1350 res=mi_get_rrecord(r);
1353 ret=mi_parse_wp_res(res);
1359 char *mi_res_value(mi_h *h)
1361 mi_results *r=mi_res_done_var(h,"value");
1364 if (r && r->type==t_const)
1373 mi_output *mi_get_stop_record(mi_output *r)
1377 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
1378 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
1386 char *reason_names[]=
1389 "watchpoint-trigger",
1390 "read-watchpoint-trigger",
1391 "access-watchpoint-trigger",
1393 "function-finished",
1395 "end-stepping-range",
1403 enum mi_stop_reason reason_values[]=
1406 sr_wp_trigger, sr_read_wp_trigger, sr_access_wp_trigger, sr_wp_scope,
1407 sr_function_finished, sr_location_reached, sr_end_stepping_range,
1408 sr_exited_signalled, sr_exited, sr_exited_normally,
1413 char *reason_expl[]=
1418 "Access watchpoint",
1419 "Watchpoint out of scope",
1420 "Function finished",
1424 "Exited with error",
1429 enum mi_stop_reason mi_reason_str_to_enum(const char *s)
1433 for (i=0; i<sizeof(reason_names)/sizeof(char *); i++)
1434 if (strcmp(reason_names[i],s)==0)
1435 return reason_values[i];
1439 const char *mi_reason_enum_to_str(enum mi_stop_reason r)
1444 return "Unknown (temp bkp?)";
1445 for (i=0; i<sizeof(reason_values)/sizeof(char *); i++)
1446 if (reason_values[i]==r)
1447 return reason_expl[i];
1451 mi_stop *mi_get_stopped(mi_results *r)
1453 mi_stop *res=mi_alloc_stop();
1459 if (r->type==t_const)
1461 if (strcmp(r->var,"reason")==0)
1462 res->reason=mi_reason_str_to_enum(r->v.cstr);
1463 else if (!res->have_thread_id && strcmp(r->var,"thread-id")==0)
1465 res->have_thread_id=1;
1466 res->thread_id=atoi(r->v.cstr);
1468 else if (!res->have_bkptno && strcmp(r->var,"bkptno")==0)
1471 res->bkptno=atoi(r->v.cstr);
1473 else if (!res->have_bkptno && strcmp(r->var,"wpnum")==0)
1476 res->wpno=atoi(r->v.cstr);
1478 else if (strcmp(r->var,"gdb-result-var")==0)
1480 res->gdb_result_var=r->v.cstr;
1483 else if (strcmp(r->var,"return-value")==0)
1485 res->return_value=r->v.cstr;
1488 else if (strcmp(r->var,"signal-name")==0)
1490 res->signal_name=r->v.cstr;
1493 else if (strcmp(r->var,"signal-meaning")==0)
1495 res->signal_meaning=r->v.cstr;
1498 else if (!res->have_exit_code && strcmp(r->var,"exit-code")==0)
1500 res->have_exit_code=1;
1501 res->exit_code=atoi(r->v.cstr);
1504 else // tuple or list
1506 if (strcmp(r->var,"frame")==0)
1507 res->frame=mi_parse_frame(r->v.rs);
1508 else if (!res->wp && strcmp(r->var,"wpt")==0)
1509 res->wp=mi_get_wp(r->v.rs,wm_write);
1510 else if (!res->wp && strcmp(r->var,"hw-rwpt")==0)
1511 res->wp=mi_get_wp(r->v.rs,wm_read);
1512 else if (!res->wp && strcmp(r->var,"hw-awpt")==0)
1513 res->wp=mi_get_wp(r->v.rs,wm_rw);
1514 else if (!(res->wp_old || res->wp_val) && strcmp(r->var,"value")==0)
1516 mi_results *p=r->v.rs;
1519 if (strcmp(p->var,"value")==0 || strcmp(p->var,"new")==0)
1521 res->wp_val=p->v.cstr;
1524 else if (strcmp(p->var,"old")==0)
1526 res->wp_old=p->v.cstr;
1539 mi_stop *mi_res_stop(mi_h *h)
1541 mi_output *o=mi_retire_response(h);
1546 mi_output *sr=mi_get_stop_record(o);
1548 stop=mi_get_stopped(sr->c);
1555 int mi_get_read_memory(mi_h *h, unsigned char *dest, unsigned ws, int *na,
1556 unsigned long *addr)
1559 mi_results *res=mi_res_done_var(h,"memory"), *r;
1564 if (r && r->type==t_list && ws==1)
1567 if (r->type!=t_tuple)
1569 mi_free_results(res);
1575 if (r->type==t_list && strcmp(r->var,"data")==0)
1577 mi_results *data=r->v.rs;
1579 if (data && data->type==t_const &&
1580 strcmp(data->v.cstr,"N/A")==0)
1585 if (data->type==t_const)
1586 *(dest++)=strtol(data->v.cstr,&end,0);
1590 else if (r->type==t_const && strcmp(r->var,"addr")==0)
1594 *addr=strtoul(r->v.cstr,&end,0);
1600 mi_free_results(res);
1604 mi_asm_insn *mi_parse_insn(mi_results *c)
1606 mi_asm_insn *res=NULL, *cur=NULL;
1612 if (c->type==t_tuple)
1615 res=cur=mi_alloc_asm_insn();
1618 cur->next=mi_alloc_asm_insn();
1623 mi_free_asm_insn(res);
1629 if (sub->type==t_const)
1631 if (strcmp(sub->var,"address")==0)
1632 cur->addr=(void *)strtoul(sub->v.cstr,&end,0);
1633 else if (strcmp(sub->var,"func-name")==0)
1635 cur->func=sub->v.cstr;
1638 else if (strcmp(sub->var,"offset")==0)
1639 cur->offset=atoi(sub->v.cstr);
1640 else if (strcmp(sub->var,"inst")==0)
1642 cur->inst=sub->v.cstr;
1654 mi_asm_insns *mi_parse_insns(mi_results *c)
1656 mi_asm_insns *res=NULL, *cur=NULL;
1663 if (strcmp(c->var,"src_and_asm_line")==0 && c->type==t_tuple)
1666 res=cur=mi_alloc_asm_insns();
1669 cur->next=mi_alloc_asm_insns();
1674 mi_free_asm_insns(res);
1682 if (sub->type==t_const)
1684 if (strcmp(sub->var,"line")==0)
1685 cur->line=atoi(sub->v.cstr);
1686 else if (strcmp(sub->var,"file")==0)
1688 cur->file=sub->v.cstr;
1692 else if (sub->type==t_list)
1694 if (strcmp(sub->var,"line_asm_insn")==0)
1695 cur->ins=mi_parse_insn(sub->v.rs);
1703 {/* No source line, just instructions */
1704 res=mi_alloc_asm_insns();
1705 res->ins=mi_parse_insn(c);
1714 mi_asm_insns *mi_get_asm_insns(mi_h *h)
1716 mi_results *r=mi_res_done_var(h,"asm_insns");
1717 mi_asm_insns *f=NULL;
1719 if (r && r->type==t_list)
1720 f=mi_parse_insns(r->v.rs);
1725 mi_chg_reg *mi_parse_list_regs(mi_results *r, int *how_many)
1729 mi_chg_reg *first=NULL, *cur=NULL;
1731 /* Create the list. */
1734 if (c->type==t_const && !c->var)
1737 cur=cur->next=mi_alloc_chg_reg();
1739 first=cur=mi_alloc_chg_reg();
1742 cur->name=c->v.cstr;
1755 mi_chg_reg *mi_get_list_registers(mi_h *h, int *how_many)
1757 mi_results *r=mi_res_done_var(h,"register-names");
1760 if (r && r->type==t_list)
1761 l=mi_parse_list_regs(r->v.rs,how_many);
1766 mi_chg_reg *mi_parse_list_changed_regs(mi_results *r)
1769 mi_chg_reg *first=NULL, *cur=NULL;
1771 /* Create the list. */
1774 if (c->type==t_const && !c->var)
1777 cur=cur->next=mi_alloc_chg_reg();
1779 first=cur=mi_alloc_chg_reg();
1780 cur->reg=atoi(c->v.cstr);
1788 mi_chg_reg *mi_get_list_changed_regs(mi_h *h)
1790 mi_results *r=mi_res_done_var(h,"changed-registers");
1791 mi_chg_reg *changed=NULL;
1793 if (r && r->type==t_list)
1794 changed=mi_parse_list_changed_regs(r->v.rs);
1799 int mi_parse_reg_values(mi_results *r, mi_chg_reg *l)
1805 if (r->type==t_tuple && !r->var)
1810 if (c->type==t_const && c->var)
1812 if (strcmp(c->var,"number")==0)
1814 if (atoi(c->v.cstr)!=l->reg)
1820 else if (strcmp(c->var,"value")==0)
1836 int mi_get_reg_values(mi_h *h, mi_chg_reg *l)
1838 mi_results *r=mi_res_done_var(h,"register-values");
1841 if (r && r->type==t_list)
1842 ok=mi_parse_reg_values(r->v.rs,l);
1847 int mi_parse_list_regs_l(mi_results *r, mi_chg_reg *l)
1851 if (r->type==t_const && !r->var)
1864 int mi_get_list_registers_l(mi_h *h, mi_chg_reg *l)
1866 mi_results *r=mi_res_done_var(h,"register-names");
1869 if (r && r->type==t_list)
1870 ok=mi_parse_list_regs_l(r->v.rs,l);
1875 mi_chg_reg *mi_parse_reg_values_l(mi_results *r, int *how_many)
1878 mi_chg_reg *first=NULL, *cur=NULL;
1883 if (r->type==t_tuple && !r->var)
1887 cur=cur->next=mi_alloc_chg_reg();
1889 first=cur=mi_alloc_chg_reg();
1892 if (c->type==t_const && c->var)
1894 if (strcmp(c->var,"number")==0)
1897 cur->reg=atoi(c->v.cstr);
1900 else if (strcmp(c->var,"value")==0)
1916 mi_chg_reg *mi_get_reg_values_l(mi_h *h, int *how_many)
1918 mi_results *r=mi_res_done_var(h,"register-values");
1919 mi_chg_reg *rgs=NULL;
1921 if (r && r->type==t_list)
1922 rgs=mi_parse_reg_values_l(r->v.rs,how_many);