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++)
66 d=r->v.cstr=mi_malloc(len+1);
69 for (s=str; *s && !EndOfStr(s); s++, d++)
96 /* TODO: What's a valid variable name?
97 I'll assume a-zA-Z0-9_- */
99 int mi_is_var_name_char(char c)
101 return isalnum(c) || c=='-' || c=='_';
104 char *mi_get_var_name(const char *str, const char **end)
110 for (s=str; *s && mi_is_var_name_char(*s); s++);
128 int mi_get_list_res(mi_results *r, const char *str, const char **end, char closeC)
130 mi_results *last_r, *rs;
135 rs=mi_get_result(str,&str);
157 int mi_get_tuple_val(mi_results *r, const char *str, const char **end)
159 mi_results *last_r, *rs;
164 rs=mi_alloc_results();
165 if (!rs || !mi_get_value(rs,str,&str))
170 /* Note that rs->var is NULL, that indicates that's just a value and not
191 #endif /* __APPLE__ */
193 int mi_get_tuple(mi_results *r, const char *str, const char **end)
203 {/* Special case: empty tuple */
208 if (mi_is_var_name_char(*str))
209 return mi_get_list_res(r,str,end,'}');
210 return mi_get_tuple_val(r,str,end);
211 #else /* __APPLE__ */
212 return mi_get_list_res(r,str,end,'}');
213 #endif /* __APPLE__ */
216 int mi_get_list_val(mi_results *r, const char *str, const char **end)
218 mi_results *last_r, *rs;
223 rs=mi_alloc_results();
224 if (!rs || !mi_get_value(rs,str,&str))
229 /* Note that rs->var is NULL, that indicates that's just a value and not
251 int mi_get_list(mi_results *r, const char *str, const char **end)
261 {/* Special case: empty list */
265 /* Comment: I think they could choose () for values. Is confusing in this way. */
266 if (mi_is_var_name_char(*str))
267 return mi_get_list_res(r,str,end,']');
268 return mi_get_list_val(r,str,end);
271 int mi_get_value(mi_results *r, const char *str, const char **end)
276 return mi_get_cstring_r(r,str,end);
278 return mi_get_tuple(r,str,end);
280 return mi_get_list(r,str,end);
286 mi_results *mi_get_result(const char *str, const char **end)
291 var=mi_get_var_name(str,&str);
295 r=mi_alloc_results();
303 if (!mi_get_value(r,str,end))
312 mi_output *mi_get_results_alone(mi_output *r,const char *str)
314 mi_results *last_r, *rs;
328 rs=mi_get_result(str,&str);
342 mi_output *mi_parse_result_record(mi_output *r,const char *str)
344 r->type=MI_T_RESULT_RECORD;
346 /* Solve the result-class. */
347 if (strncmp(str,"done",4)==0)
350 r->tclass=MI_CL_DONE;
352 else if (strncmp(str,"running",7)==0)
355 r->tclass=MI_CL_RUNNING;
357 else if (strncmp(str,"connected",9)==0)
360 r->tclass=MI_CL_CONNECTED;
362 else if (strncmp(str,"error",5)==0)
365 r->tclass=MI_CL_ERROR;
367 else if (strncmp(str,"exit",4)==0)
370 r->tclass=MI_CL_EXIT;
374 mi_error=MI_UNKNOWN_RESULT;
378 return mi_get_results_alone(r,str);
381 mi_output *mi_parse_asyn(mi_output *r,const char *str)
383 r->type=MI_T_OUT_OF_BAND;
384 r->stype=MI_ST_ASYNC;
386 if (strncmp(str,"stopped",7)==0)
388 r->tclass=MI_CL_STOPPED;
390 return mi_get_results_alone(r,str);
392 if (strncmp(str,"download",8)==0)
394 r->tclass=MI_CL_DOWNLOAD;
396 return mi_get_results_alone(r,str);
398 mi_error=MI_UNKNOWN_ASYNC;
403 mi_output *mi_parse_exec_asyn(mi_output *r,const char *str)
405 r->sstype=MI_SST_EXEC;
406 return mi_parse_asyn(r,str);
409 mi_output *mi_parse_status_asyn(mi_output *r,const char *str)
411 r->sstype=MI_SST_STATUS;
412 return mi_parse_asyn(r,str);
415 mi_output *mi_parse_notify_asyn(mi_output *r,const char *str)
417 r->sstype=MI_SST_NOTIFY;
418 return mi_parse_asyn(r,str);
421 mi_output *mi_console(mi_output *r,const char *str)
423 r->type=MI_T_OUT_OF_BAND;
424 r->stype=MI_ST_STREAM;
425 r->c=mi_alloc_results();
426 if (!r->c || !mi_get_cstring_r(r->c,str,NULL))
434 mi_output *mi_console_stream(mi_output *r,const char *str)
436 r->sstype=MI_SST_CONSOLE;
437 return mi_console(r,str);
440 mi_output *mi_target_stream(mi_output *r,const char *str)
442 r->sstype=MI_SST_TARGET;
443 return mi_console(r,str);
446 mi_output *mi_log_stream(mi_output *r,const char *str)
448 r->sstype=MI_SST_LOG;
449 return mi_console(r,str);
452 mi_output *mi_parse_gdb_output(const char *str)
456 mi_output *r=mi_alloc_output();
459 mi_error=MI_OUT_OF_MEMORY;
466 return mi_parse_result_record(r,str);
468 return mi_parse_exec_asyn(r,str);
470 return mi_parse_status_asyn(r,str);
472 return mi_parse_notify_asyn(r,str);
474 return mi_console_stream(r,str);
476 return mi_target_stream(r,str);
478 return mi_log_stream(r,str);
484 mi_output *mi_get_rrecord(mi_output *r)
490 if (r->type==MI_T_RESULT_RECORD)
497 mi_results *mi_get_var_r(mi_results *r, const char *var)
501 if (strcmp(r->var,var)==0)
508 mi_results *mi_get_var(mi_output *res, const char *var)
512 return mi_get_var_r(res->c,var);
515 int mi_get_async_stop_reason(mi_output *r, char **reason)
522 if (r->type==MI_T_RESULT_RECORD && r->tclass==MI_CL_ERROR)
524 if (r->c->type==t_const)
525 *reason=r->c->v.cstr;
528 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
529 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
535 if (strcmp(p->var,"reason")==0)
545 if (*reason==NULL && found_stopped)
547 *reason=strdup("unknown (temp bkpt?)");
553 mi_frames *mi_get_async_frame(mi_output *r)
557 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
558 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
563 if (strcmp(p->var,"frame")==0)
564 return mi_parse_frame(p->v.rs);
573 int mi_res_simple(mi_h *h, int tclass, int accert_ret)
578 r=mi_get_response_blk(h);
579 res=mi_get_rrecord(r);
582 ret=res->tclass==tclass;
589 int mi_res_simple_done(mi_h *h)
591 return mi_res_simple(h,MI_CL_DONE,0);
594 int mi_res_simple_exit(mi_h *h)
596 return mi_res_simple(h,MI_CL_EXIT,1);
599 int mi_res_simple_running(mi_h *h)
601 return mi_res_simple(h,MI_CL_RUNNING,0);
604 int mi_res_simple_connected(mi_h *h)
606 return mi_res_simple(h,MI_CL_CONNECTED,0);
609 mi_results *mi_res_var(mi_h *h, const char *var, int tclass)
612 mi_results *the_var=NULL;
614 r=mi_get_response_blk(h);
615 /* All the code that follows is "NULL" tolerant. */
616 /* Look for the result-record. */
617 res=mi_get_rrecord(r);
618 /* Look for the desired var. */
619 if (res && res->tclass==tclass)
620 the_var=mi_get_var(res,var);
621 /* Release all but the one we want. */
622 mi_free_output_but(r,NULL,the_var);
626 mi_results *mi_res_done_var(mi_h *h, const char *var)
628 return mi_res_var(h,var,MI_CL_DONE);
631 mi_frames *mi_parse_frame(mi_results *c)
633 mi_frames *res=mi_alloc_frames();
640 if (c->type==t_const)
642 if (strcmp(c->var,"level")==0)
643 res->level=atoi(c->v.cstr);
644 else if (strcmp(c->var,"addr")==0)
645 res->addr=(void *)strtoul(c->v.cstr,&end,0);
646 else if (strcmp(c->var,"func")==0)
651 else if (strcmp(c->var,"file")==0)
656 else if (strcmp(c->var,"from")==0)
661 else if (strcmp(c->var,"line")==0)
662 res->line=atoi(c->v.cstr);
664 else if (c->type==t_list && strcmp(c->var,"args")==0)
675 mi_frames *mi_res_frame(mi_h *h)
677 mi_results *r=mi_res_done_var(h,"frame");
680 if (r && r->type==t_tuple)
681 f=mi_parse_frame(r->v.rs);
686 mi_frames *mi_res_frames_array(mi_h *h, const char *var)
688 mi_results *r=mi_res_done_var(h,var), *c;
689 mi_frames *res=NULL, *nframe, *last=NULL;
694 if (r->type!=t_list && r->type!=t_tuple)
705 if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
707 nframe=mi_parse_frame(c->v.rs);
723 mi_frames *mi_res_frames_list(mi_h *h)
726 mi_frames *ret=NULL, *nframe, *last=NULL;
729 r=mi_get_response_blk(h);
730 res=mi_get_rrecord(r);
731 if (res && res->tclass==MI_CL_DONE)
736 if (strcmp(c->var,"frame")==0 && c->type==t_tuple)
738 nframe=mi_parse_frame(c->v.rs);
755 int mi_get_thread_ids(mi_output *res, int **list)
757 mi_results *vids, *lids;
761 vids=mi_get_var(res,"number-of-threads");
762 lids=mi_get_var(res,"thread-ids");
763 if (vids && vids->type==t_const &&
764 lids && lids->type==t_tuple)
766 ids=atoi(vids->v.cstr);
770 lst=(int *)mi_calloc(ids,sizeof(int));
777 if (strcmp(lids->var,"thread-id")==0 && lids->type==t_const)
778 lst[i++]=atoi(lids->v.cstr);
790 int mi_res_thread_ids(mi_h *h, int **list)
795 r=mi_get_response_blk(h);
796 res=mi_get_rrecord(r);
797 if (res && res->tclass==MI_CL_DONE)
798 ids=mi_get_thread_ids(res,list);
803 enum mi_gvar_lang mi_lang_str_to_enum(const char *lang)
805 enum mi_gvar_lang lg=lg_unknown;
807 if (strcmp(lang,"C")==0)
809 else if (strcmp(lang,"C++")==0)
811 else if (strcmp(lang,"Java")==0)
817 const char *mi_lang_enum_to_str(enum mi_gvar_lang lang)
840 enum mi_gvar_fmt mi_format_str_to_enum(const char *format)
842 enum mi_gvar_fmt fmt=fm_natural;
844 if (strcmp(format,"binary")==0)
846 else if (strcmp(format,"decimal")==0)
848 else if (strcmp(format,"hexadecimal")==0)
850 else if (strcmp(format,"octal")==0)
856 const char *mi_format_enum_to_str(enum mi_gvar_fmt format)
886 char mi_format_enum_to_char(enum mi_gvar_fmt format)
916 mi_gvar *mi_get_gvar(mi_output *o, mi_gvar *cur, const char *expression)
919 mi_gvar *res=cur ? cur : mi_alloc_gvar();
926 res->exp=strdup(expression);
929 if (r->type==t_const)
931 if (strcmp(r->var,"name")==0)
937 else if (strcmp(r->var,"numchild")==0)
939 res->numchild=atoi(r->v.cstr);
941 else if (strcmp(r->var,"type")==0)
947 if (l && res->type[l-1]=='*')
950 else if (strcmp(r->var,"lang")==0)
952 res->lang=mi_lang_str_to_enum(r->v.cstr);
954 else if (strcmp(r->var,"exp")==0)
960 else if (strcmp(r->var,"format")==0)
962 res->format=mi_format_str_to_enum(r->v.cstr);
964 else if (strcmp(r->var,"attr")==0)
965 { /* Note: gdb 6.1.1 have only this: */
966 if (strcmp(r->v.cstr,"editable")==0)
967 res->attr=MI_ATTR_EDITABLE;
968 else /* noneditable */
969 res->attr=MI_ATTR_NONEDITABLE;
977 mi_gvar *mi_res_gvar(mi_h *h, mi_gvar *cur, const char *expression)
982 r=mi_get_response_blk(h);
983 res=mi_get_rrecord(r);
984 if (res && res->tclass==MI_CL_DONE)
985 gvar=mi_get_gvar(res,cur,expression);
990 mi_gvar_chg *mi_get_gvar_chg(mi_results *r)
994 if (r->type!=t_const)
996 n=mi_alloc_gvar_chg();
1001 if (r->type==t_const)
1003 if (strcmp(r->var,"name")==0)
1008 else if (strcmp(r->var,"in_scope")==0)
1010 n->in_scope=strcmp(r->v.cstr,"true")==0;
1012 else if (strcmp(r->var,"new_type")==0)
1014 n->new_type=r->v.cstr;
1017 else if (strcmp(r->var,"new_num_children")==0)
1019 n->new_num_children=atoi(r->v.cstr);
1021 // type_changed="false" is the default
1029 int mi_res_changelist(mi_h *h, mi_gvar_chg **changed)
1031 mi_gvar_chg *last, *n;
1032 mi_results *res=mi_res_done_var(h,"changelist"), *r;
1043 if (res->type==t_list)
1044 {// MI v2 a list of tuples
1047 if (r->type==t_tuple)
1049 n=mi_get_gvar_chg(r->v.rs);
1063 else if (res->type==t_tuple)
1064 {// MI v1 a tuple with all together *8-P
1067 if (r->type==t_const) /* Just in case. */
1069 if (strcmp(r->var,"name")==0)
1072 {/* Add to the list*/
1080 n=mi_alloc_gvar_chg();
1083 mi_free_gvar_chg(*changed);
1089 else if (strcmp(r->var,"in_scope")==0)
1091 n->in_scope=strcmp(r->v.cstr,"true")==0;
1093 else if (strcmp(r->var,"new_type")==0)
1095 n->new_type=r->v.cstr;
1098 else if (strcmp(r->var,"new_num_children")==0)
1100 n->new_num_children=atoi(r->v.cstr);
1102 // type_changed="false" is the default
1107 {/* Add to the list*/
1116 mi_free_results(res);
1121 int mi_get_children(mi_results *ch, mi_gvar *v)
1123 mi_gvar *cur=NULL, *aux;
1124 int i=0, count=v->numchild, l;
1128 if (strcmp(ch->var,"child")==0 && ch->type==t_tuple && i<count)
1130 mi_results *r=ch->v.rs;
1131 aux=mi_alloc_gvar();
1140 cur->depth=v->depth+1;
1144 if (r->type==t_const)
1146 if (strcmp(r->var,"name")==0)
1148 cur->name=r->v.cstr;
1151 else if (strcmp(r->var,"exp")==0)
1156 else if (strcmp(r->var,"type")==0)
1158 cur->type=r->v.cstr;
1160 l=strlen(cur->type);
1161 if (l && cur->type[l-1]=='*')
1164 else if (strcmp(r->var,"value")==0)
1166 cur->value=r->v.cstr;
1169 else if (strcmp(r->var,"numchild")==0)
1171 cur->numchild=atoi(r->v.cstr);
1182 return i==v->numchild;
1185 int mi_res_children(mi_h *h, mi_gvar *v)
1190 r=mi_get_response_blk(h);
1191 res=mi_get_rrecord(r);
1192 if (res && res->tclass==MI_CL_DONE)
1194 mi_results *num=mi_get_var(res,"numchild");
1195 if (num && num->type==t_const)
1197 v->numchild=atoi(num->v.cstr);
1200 mi_free_gvar(v->child);
1205 mi_results *ch =mi_get_var(res,"children");
1206 if (ch && ch->type!=t_const) /* MI v1 tuple, MI v2 list */
1207 ok=mi_get_children(ch->v.rs,v);
1217 mi_bkpt *mi_get_bkpt(mi_results *p)
1222 res=mi_alloc_bkpt();
1227 if (p->type==t_const && p->var)
1229 if (strcmp(p->var,"number")==0)
1230 res->number=atoi(p->v.cstr);
1231 else if (strcmp(p->var,"type")==0)
1233 if (strcmp(p->v.cstr,"breakpoint")==0)
1234 res->type=t_breakpoint;
1236 res->type=t_unknown;
1238 else if (strcmp(p->var,"disp")==0)
1240 if (strcmp(p->v.cstr,"keep")==0)
1242 else if (strcmp(p->v.cstr,"del")==0)
1245 res->disp=d_unknown;
1247 else if (strcmp(p->var,"enabled")==0)
1248 res->enabled=p->v.cstr[0]=='y';
1249 else if (strcmp(p->var,"addr")==0)
1250 res->addr=(void *)strtoul(p->v.cstr,&end,0);
1251 else if (strcmp(p->var,"func")==0)
1253 res->func=p->v.cstr;
1256 else if (strcmp(p->var,"file")==0)
1258 res->file=p->v.cstr;
1261 else if (strcmp(p->var,"line")==0)
1262 res->line=atoi(p->v.cstr);
1263 else if (strcmp(p->var,"times")==0)
1264 res->times=atoi(p->v.cstr);
1265 else if (strcmp(p->var,"ignore")==0)
1266 res->ignore=atoi(p->v.cstr);
1267 else if (strcmp(p->var,"cond")==0)
1269 res->cond=p->v.cstr;
1278 mi_bkpt *mi_res_bkpt(mi_h *h)
1280 mi_results *r=mi_res_done_var(h,"bkpt");
1283 if (r && r->type==t_tuple)
1284 b=mi_get_bkpt(r->v.rs);
1289 mi_wp *mi_get_wp(mi_results *p, enum mi_wp_mode m)
1291 mi_wp *res=mi_alloc_wp();
1298 if (p->type==t_const && p->var)
1300 if (strcmp(p->var,"number")==0)
1302 res->number=atoi(p->v.cstr);
1305 else if (strcmp(p->var,"exp")==0)
1317 mi_wp *mi_parse_wp_res(mi_output *r)
1320 enum mi_wp_mode m=wm_unknown;
1322 /* The info is in a result wpt=... */
1328 if (strcmp(p->var,"wpt")==0)
1330 else if (strcmp(p->var,"hw-rwpt")==0)
1332 else if (strcmp(p->var,"hw-awpt")==0)
1339 if (!p || p->type!=t_tuple)
1341 /* Scan the values inside it. */
1342 return mi_get_wp(p->v.rs,m);
1345 mi_wp *mi_res_wp(mi_h *h)
1350 r=mi_get_response_blk(h);
1351 res=mi_get_rrecord(r);
1354 ret=mi_parse_wp_res(res);
1360 char *mi_res_value(mi_h *h)
1362 mi_results *r=mi_res_done_var(h,"value");
1365 if (r && r->type==t_const)
1374 mi_output *mi_get_stop_record(mi_output *r)
1378 if (r->type==MI_T_OUT_OF_BAND && r->stype==MI_ST_ASYNC &&
1379 r->sstype==MI_SST_EXEC && r->tclass==MI_CL_STOPPED)
1387 char *reason_names[]=
1390 "watchpoint-trigger",
1391 "read-watchpoint-trigger",
1392 "access-watchpoint-trigger",
1394 "function-finished",
1396 "end-stepping-range",
1404 enum mi_stop_reason reason_values[]=
1407 sr_wp_trigger, sr_read_wp_trigger, sr_access_wp_trigger, sr_wp_scope,
1408 sr_function_finished, sr_location_reached, sr_end_stepping_range,
1409 sr_exited_signalled, sr_exited, sr_exited_normally,
1414 char *reason_expl[]=
1419 "Access watchpoint",
1420 "Watchpoint out of scope",
1421 "Function finished",
1425 "Exited with error",
1430 enum mi_stop_reason mi_reason_str_to_enum(const char *s)
1434 for (i=0; i<sizeof(reason_names)/sizeof(char *); i++)
1435 if (strcmp(reason_names[i],s)==0)
1436 return reason_values[i];
1440 const char *mi_reason_enum_to_str(enum mi_stop_reason r)
1445 return "Unknown (temp bkp?)";
1446 for (i=0; i<sizeof(reason_values)/sizeof(char *); i++)
1447 if (reason_values[i]==r)
1448 return reason_expl[i];
1452 mi_stop *mi_get_stopped(mi_results *r)
1454 mi_stop *res=mi_alloc_stop();
1460 if (r->type==t_const)
1462 if (strcmp(r->var,"reason")==0)
1463 res->reason=mi_reason_str_to_enum(r->v.cstr);
1464 else if (!res->have_thread_id && strcmp(r->var,"thread-id")==0)
1466 res->have_thread_id=1;
1467 res->thread_id=atoi(r->v.cstr);
1469 else if (!res->have_bkptno && strcmp(r->var,"bkptno")==0)
1472 res->bkptno=atoi(r->v.cstr);
1474 else if (!res->have_bkptno && strcmp(r->var,"wpnum")==0)
1477 res->wpno=atoi(r->v.cstr);
1479 else if (strcmp(r->var,"gdb-result-var")==0)
1481 res->gdb_result_var=r->v.cstr;
1484 else if (strcmp(r->var,"return-value")==0)
1486 res->return_value=r->v.cstr;
1489 else if (strcmp(r->var,"signal-name")==0)
1491 res->signal_name=r->v.cstr;
1494 else if (strcmp(r->var,"signal-meaning")==0)
1496 res->signal_meaning=r->v.cstr;
1499 else if (!res->have_exit_code && strcmp(r->var,"exit-code")==0)
1501 res->have_exit_code=1;
1502 res->exit_code=atoi(r->v.cstr);
1505 else // tuple or list
1507 if (strcmp(r->var,"frame")==0)
1508 res->frame=mi_parse_frame(r->v.rs);
1509 else if (!res->wp && strcmp(r->var,"wpt")==0)
1510 res->wp=mi_get_wp(r->v.rs,wm_write);
1511 else if (!res->wp && strcmp(r->var,"hw-rwpt")==0)
1512 res->wp=mi_get_wp(r->v.rs,wm_read);
1513 else if (!res->wp && strcmp(r->var,"hw-awpt")==0)
1514 res->wp=mi_get_wp(r->v.rs,wm_rw);
1515 else if (!(res->wp_old || res->wp_val) && strcmp(r->var,"value")==0)
1517 mi_results *p=r->v.rs;
1520 if (strcmp(p->var,"value")==0 || strcmp(p->var,"new")==0)
1522 res->wp_val=p->v.cstr;
1525 else if (strcmp(p->var,"old")==0)
1527 res->wp_old=p->v.cstr;
1540 mi_stop *mi_res_stop(mi_h *h)
1542 mi_output *o=mi_retire_response(h);
1547 mi_output *sr=mi_get_stop_record(o);
1549 stop=mi_get_stopped(sr->c);
1556 int mi_get_read_memory(mi_h *h, unsigned char *dest, unsigned ws, int *na,
1557 unsigned long *addr)
1560 mi_results *res=mi_res_done_var(h,"memory"), *r;
1565 if (r && r->type==t_list && ws==1)
1568 if (r->type!=t_tuple)
1570 mi_free_results(res);
1576 if (r->type==t_list && strcmp(r->var,"data")==0)
1578 mi_results *data=r->v.rs;
1580 if (data && data->type==t_const &&
1581 strcmp(data->v.cstr,"N/A")==0)
1586 if (data->type==t_const)
1587 *(dest++)=strtol(data->v.cstr,&end,0);
1591 else if (r->type==t_const && strcmp(r->var,"addr")==0)
1595 *addr=strtoul(r->v.cstr,&end,0);
1601 mi_free_results(res);
1605 mi_asm_insn *mi_parse_insn(mi_results *c)
1607 mi_asm_insn *res=NULL, *cur=NULL;
1613 if (c->type==t_tuple)
1616 res=cur=mi_alloc_asm_insn();
1619 cur->next=mi_alloc_asm_insn();
1624 mi_free_asm_insn(res);
1630 if (sub->type==t_const)
1632 if (strcmp(sub->var,"address")==0)
1633 cur->addr=(void *)strtoul(sub->v.cstr,&end,0);
1634 else if (strcmp(sub->var,"func-name")==0)
1636 cur->func=sub->v.cstr;
1639 else if (strcmp(sub->var,"offset")==0)
1640 cur->offset=atoi(sub->v.cstr);
1641 else if (strcmp(sub->var,"inst")==0)
1643 cur->inst=sub->v.cstr;
1655 mi_asm_insns *mi_parse_insns(mi_results *c)
1657 mi_asm_insns *res=NULL, *cur=NULL;
1664 if (strcmp(c->var,"src_and_asm_line")==0 && c->type==t_tuple)
1667 res=cur=mi_alloc_asm_insns();
1670 cur->next=mi_alloc_asm_insns();
1675 mi_free_asm_insns(res);
1683 if (sub->type==t_const)
1685 if (strcmp(sub->var,"line")==0)
1686 cur->line=atoi(sub->v.cstr);
1687 else if (strcmp(sub->var,"file")==0)
1689 cur->file=sub->v.cstr;
1693 else if (sub->type==t_list)
1695 if (strcmp(sub->var,"line_asm_insn")==0)
1696 cur->ins=mi_parse_insn(sub->v.rs);
1704 {/* No source line, just instructions */
1705 res=mi_alloc_asm_insns();
1706 res->ins=mi_parse_insn(c);
1715 mi_asm_insns *mi_get_asm_insns(mi_h *h)
1717 mi_results *r=mi_res_done_var(h,"asm_insns");
1718 mi_asm_insns *f=NULL;
1720 if (r && r->type==t_list)
1721 f=mi_parse_insns(r->v.rs);
1726 mi_chg_reg *mi_parse_list_regs(mi_results *r, int *how_many)
1730 mi_chg_reg *first=NULL, *cur=NULL;
1732 /* Create the list. */
1735 if (c->type==t_const && !c->var)
1738 cur=cur->next=mi_alloc_chg_reg();
1740 first=cur=mi_alloc_chg_reg();
1741 cur->name=c->v.cstr;
1753 mi_chg_reg *mi_get_list_registers(mi_h *h, int *how_many)
1755 mi_results *r=mi_res_done_var(h,"register-names");
1758 if (r && r->type==t_list)
1759 l=mi_parse_list_regs(r->v.rs,how_many);
1764 mi_chg_reg *mi_parse_list_changed_regs(mi_results *r)
1767 mi_chg_reg *first=NULL, *cur=NULL;
1769 /* Create the list. */
1772 if (c->type==t_const && !c->var)
1775 cur=cur->next=mi_alloc_chg_reg();
1777 first=cur=mi_alloc_chg_reg();
1778 cur->reg=atoi(c->v.cstr);
1786 mi_chg_reg *mi_get_list_changed_regs(mi_h *h)
1788 mi_results *r=mi_res_done_var(h,"changed-registers");
1789 mi_chg_reg *changed=NULL;
1791 if (r && r->type==t_list)
1792 changed=mi_parse_list_changed_regs(r->v.rs);
1797 int mi_parse_reg_values(mi_results *r, mi_chg_reg *l)
1803 if (r->type==t_tuple && !r->var)
1808 if (c->type==t_const && c->var)
1810 if (strcmp(c->var,"number")==0)
1812 if (atoi(c->v.cstr)!=l->reg)
1818 else if (strcmp(c->var,"value")==0)
1834 int mi_get_reg_values(mi_h *h, mi_chg_reg *l)
1836 mi_results *r=mi_res_done_var(h,"register-values");
1839 if (r && r->type==t_list)
1840 ok=mi_parse_reg_values(r->v.rs,l);
1845 int mi_parse_list_regs_l(mi_results *r, mi_chg_reg *l)
1849 if (r->type==t_const && !r->var)
1862 int mi_get_list_registers_l(mi_h *h, mi_chg_reg *l)
1864 mi_results *r=mi_res_done_var(h,"register-names");
1867 if (r && r->type==t_list)
1868 ok=mi_parse_list_regs_l(r->v.rs,l);
1873 mi_chg_reg *mi_parse_reg_values_l(mi_results *r, int *how_many)
1876 mi_chg_reg *first=NULL, *cur=NULL;
1881 if (r->type==t_tuple && !r->var)
1885 cur=cur->next=mi_alloc_chg_reg();
1887 first=cur=mi_alloc_chg_reg();
1890 if (c->type==t_const && c->var)
1892 if (strcmp(c->var,"number")==0)
1894 cur->reg=atoi(c->v.cstr);
1897 else if (strcmp(c->var,"value")==0)
1912 mi_chg_reg *mi_get_reg_values_l(mi_h *h, int *how_many)
1914 mi_results *r=mi_res_done_var(h,"register-values");
1915 mi_chg_reg *rgs=NULL;
1917 if (r && r->type==t_list)
1918 rgs=mi_parse_reg_values_l(r->v.rs,how_many);