2 Property changes on: src/netbeans.c
3 ___________________________________________________________________
8 Property changes on: src/term.c
9 ___________________________________________________________________
14 Property changes on: src/term.h
15 ___________________________________________________________________
20 Property changes on: src/digraph.c
21 ___________________________________________________________________
26 Property changes on: src/ex_docmd.c
27 ___________________________________________________________________
32 Property changes on: src/ex_cmds.c
33 ___________________________________________________________________
38 Property changes on: src/message.c
39 ___________________________________________________________________
44 Property changes on: src/ex_cmds.h
45 ___________________________________________________________________
50 Property changes on: src/mark.c
51 ___________________________________________________________________
56 Property changes on: src/ascii.h
57 ___________________________________________________________________
62 Property changes on: src/termlib.c
63 ___________________________________________________________________
68 Property changes on: src/if_perlsfio.c
69 ___________________________________________________________________
74 Property changes on: src/menu.c
75 ___________________________________________________________________
80 Property changes on: src/ex_cmds2.c
81 ___________________________________________________________________
85 Index: src/configure.in
86 ===================================================================
87 --- src/configure.in (.../vendor/vim/current) (revision 223)
88 +++ src/configure.in (.../trunk/vim) (revision 223)
90 AC_DEFINE(FEAT_CSCOPE)
93 +dnl FEAT_GDB defined later
94 +AC_MSG_CHECKING(--enable-gdb argument)
96 + [ --enable-gdb Include GDB support.], ,
98 +AC_MSG_RESULT($enable_gdb)
100 AC_MSG_CHECKING(--enable-workshop argument)
101 AC_ARG_ENABLE(workshop,
102 [ --enable-workshop Include Sun Visual Workshop support.], ,
103 @@ -2006,6 +2013,20 @@
107 +dnl do not add pty.o when a GUI is used
108 +if test "$enable_gdb" = "yes"; then
109 + AC_DEFINE(FEAT_GDB)
110 + if test "x$GUITYPE" = "xNONE"; then
111 + GDB_SRC="gdb.c clewn/gdb_lvl2.c clewn/gdb_lvl3.c clewn/misc.c clewn/obstack.c pty.c"
112 + GDB_OBJ="objects/gdb.o objects/gdb_lvl2.o objects/gdb_lvl3.o objects/misc.o objects/obstack.o objects/pty.o"
114 + GDB_SRC="gdb.c clewn/gdb_lvl2.c clewn/gdb_lvl3.c clewn/misc.c clewn/obstack.c"
115 + GDB_OBJ="objects/gdb.o objects/gdb_lvl2.o objects/gdb_lvl3.o objects/misc.o objects/obstack.o"
121 if test "$enable_workshop" = "yes" -a -n "$SKIP_MOTIF"; then
122 AC_MSG_ERROR([cannot use workshop without Motif])
125 Property changes on: src/hangulin.c
126 ___________________________________________________________________
131 Property changes on: src/move.c
132 ___________________________________________________________________
137 ===================================================================
138 --- src/option.c (.../vendor/vim/current) (revision 223)
139 +++ src/option.c (.../trunk/vim) (revision 223)
141 {(char_u *)0L, (char_u *)0L}
145 + {"asm", NULL, P_NUM|P_VI_DEF,
146 + (char_u *)&p_asm, PV_NONE,
147 + {(char_u *)10L, (char_u *)0L}},
149 #ifdef FEAT_AUTOCHDIR
150 {"autochdir", "acd", P_BOOL|P_VI_DEF,
151 (char_u *)&p_acd, PV_NONE,
152 @@ -1153,6 +1158,14 @@
153 {(char_u *)FALSE, (char_u *)0L}
157 + {"gdbvariables", "gdbvar",P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
158 + (char_u *)&p_gvar, PV_NONE,
159 + {(char_u *)"gdb-variables", (char_u *)0L} },
160 + {"gdbprg", "gdp", P_STRING|P_EXPAND|P_VI_DEF|P_SECURE,
161 + (char_u *)&p_gdp, PV_NONE,
162 + {(char_u *)"gdb", (char_u *)0L} },
164 {"gdefault", "gd", P_BOOL|P_VI_DEF|P_VIM,
165 (char_u *)&p_gd, PV_NONE,
166 {(char_u *)FALSE, (char_u *)0L}},
168 Property changes on: src/option.c
169 ___________________________________________________________________
174 Property changes on: src/workshop.c
175 ___________________________________________________________________
180 ===================================================================
181 --- src/option.h (.../vendor/vim/current) (revision 223)
182 +++ src/option.h (.../trunk/vim) (revision 223)
184 EXTERN char_u *p_isp; /* 'isprint' */
185 EXTERN int p_js; /* 'joinspaces' */
186 EXTERN char_u *p_kp; /* 'keywordprg' */
188 +EXTERN long p_asm; /* 'asm' */
189 +EXTERN char_u *p_gvar; /* 'gdbvariables' */
190 +EXTERN char_u *p_gdp; /* 'gdbprg' */
193 EXTERN char_u *p_km; /* 'keymodel' */
196 Property changes on: src/option.h
197 ___________________________________________________________________
202 Property changes on: src/workshop.h
203 ___________________________________________________________________
207 Index: src/proto/gdb.pro
208 ===================================================================
209 --- src/proto/gdb.pro (.../vendor/vim/current) (revision 0)
210 +++ src/proto/gdb.pro (.../trunk/vim) (revision 223)
213 +gdb_handle_T *gdb_new __ARGS((void));
214 +void gdb_delete __ARGS((gdb_handle_T **));
215 +int gdb_isrunning __ARGS((gdb_handle_T *));
216 +int gdb_fd __ARGS((gdb_handle_T *));
217 +pid_t gdb_pid __ARGS((gdb_handle_T *));
218 +int gdb_isbuffer __ARGS((gdb_handle_T *, buf_T *));
219 +int gdb_allowed __ARGS((gdb_handle_T *));
220 +int gdb_event __ARGS((gdb_handle_T *));
221 +int gdb_sigchld __ARGS((gdb_handle_T *));
222 +void gdb_set_event __ARGS((gdb_handle_T *, int));
223 +void gdb_set_sigchld __ARGS((gdb_handle_T *, int));
224 +int gdb_safe_vgetc __ARGS((gdb_handle_T *));
225 +void gdb_buffer_free __ARGS((gdb_handle_T *, buf_T *));
226 +void gdb_label __ARGS((gdb_handle_T *, buf_T *, char_u *, size_t));
227 +void gdb_docmd __ARGS((gdb_handle_T *, char_u *));
228 +void gdb_setwinput __ARGS((gdb_handle_T *, char_u *));
229 +int gdb_iswinput __ARGS((gdb_handle_T *));
230 +void gdb_winput __ARGS((gdb_handle_T *));
231 +long gdb_process_output __ARGS((gdb_handle_T *, long, void *));
232 +win_T *gdb_window __ARGS((gdb_handle_T *));
233 +/* vim: set ft=c : */
235 Property changes on: src/quickfix.c
236 ___________________________________________________________________
241 ===================================================================
242 --- src/gui.c (.../vendor/vim/current) (revision 223)
243 +++ src/gui.c (.../trunk/vim) (revision 223)
244 @@ -2647,6 +2647,10 @@
248 +#if defined(FEAT_GDB) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
249 + struct timeval start_tv;
250 + gettimeofday(&start_tv, NULL);
254 * If we're going to wait a bit, update the menus and mouse shape for the
255 @@ -2673,7 +2677,35 @@
256 /* Blink when waiting for a character. Probably only does something
258 gui_mch_start_blink();
261 + while ((retval = gui_mch_wait_for_chars(wtime)) == FAIL)
263 + if (gdb_event(gdb) && gdb_allowed(gdb))
265 + gui_mch_stop_blink(); // cursor off while drawing status line
266 +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
267 + if ((wtime = gdb_process_output(gdb, wtime, (void *)&start_tv)) < 0)
269 + /* guess we got interrupted halfway */
272 + if ((wtime = gdb_process_output(gdb, wtime, NULL)) < 0)
275 + return 0; /* launch input-line window */
277 + gui_mch_start_blink();
286 retval = gui_mch_wait_for_chars(wtime);
288 gui_mch_stop_blink();
291 @@ -2689,7 +2721,27 @@
292 * 'updatetime' and if nothing is typed within that time put the
293 * K_CURSORHOLD key in the input buffer.
298 + retval = gui_mch_wait_for_chars(p_ut);
299 + if (retval == FAIL && gdb_event(gdb) && gdb_allowed(gdb))
301 + gui_mch_stop_blink(); // cursor off while drawing status line
302 + if (gdb_process_output(gdb, -1L, NULL) < 0)
304 + return 0; /* launch input-line window */
306 + gui_mch_start_blink();
314 if (gui_mch_wait_for_chars(p_ut) == OK)
318 else if (trigger_cursorhold())
319 @@ -2710,7 +2762,25 @@
326 + retval = gui_mch_wait_for_chars(-1L);
327 + if (retval == FAIL && gdb_event(gdb) && gdb_allowed(gdb))
329 + gui_mch_stop_blink(); // cursor off while drawing status line
330 + if (gdb_process_output(gdb, -1L, NULL) < 0)
332 + return 0; /* launch input-line window */
334 + gui_mch_start_blink();
340 retval = gui_mch_wait_for_chars(-1L);
344 gui_mch_stop_blink();
346 Property changes on: src/gui.c
347 ___________________________________________________________________
352 Property changes on: src/macros.h
353 ___________________________________________________________________
358 Property changes on: src/gui.h
359 ___________________________________________________________________
364 Property changes on: src/regexp.c
365 ___________________________________________________________________
370 Property changes on: src/regexp.h
371 ___________________________________________________________________
375 Index: src/config.mk.in
376 ===================================================================
377 --- src/config.mk.in (.../vendor/vim/current) (revision 223)
378 +++ src/config.mk.in (.../trunk/vim) (revision 223)
380 WORKSHOP_SRC = @WORKSHOP_SRC@
381 WORKSHOP_OBJ = @WORKSHOP_OBJ@
386 NETBEANS_SRC = @NETBEANS_SRC@
387 NETBEANS_OBJ = @NETBEANS_OBJ@
390 Property changes on: src/vim.h
391 ___________________________________________________________________
396 Property changes on: src/gui_at_fs.c
397 ___________________________________________________________________
402 Property changes on: src/gui_athena.c
403 ___________________________________________________________________
408 ===================================================================
409 --- src/structs.h (.../vendor/vim/current) (revision 223)
410 +++ src/structs.h (.../trunk/vim) (revision 223)
412 linenr_T lnum; /* line number which has this sign */
413 int typenr; /* typenr of sign */
414 signlist_T *next; /* next signlist entry */
415 -# ifdef FEAT_NETBEANS_INTG
416 +# if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GDB)
417 signlist_T *prev; /* previous entry -- for easy reordering */
432 * Argument list: Array of file names.
433 * Used for the global argument list and the argument lists local to a window.
435 Property changes on: src/structs.h
436 ___________________________________________________________________
441 Property changes on: src/ui.c
442 ___________________________________________________________________
447 Property changes on: src/getchar.c
448 ___________________________________________________________________
453 Property changes on: src/memfile.c
454 ___________________________________________________________________
459 Property changes on: src/xxd
460 ___________________________________________________________________
466 ===================================================================
467 --- src/feature.h (.../vendor/vim/current) (revision 223)
468 +++ src/feature.h (.../trunk/vim) (revision 223)
469 @@ -1210,6 +1210,24 @@
473 + * +gdb Gdb interface. Must be included through configure,
474 + * see Makefile and uncomment "--enable-gdb"
475 + * Not included when required features are missing
476 + * and use explicitly the following FEAT_NORMAL features:
477 + * FEAT_CMDWIN FEAT_EVAL FEAT_STL_OPT FEAT_MODIFY_FNAME
478 + * FEAT_SEARCHPATH FEAT_WINDOWS FEAT_QUICKFIX
481 +# if !defined(FEAT_NORMAL) || !defined(HAVE_SYS_WAIT_H) || !defined(HAVE_FCNTL_H)
485 +# define FEAT_SIGNS /* include +signs */
491 * +balloon_eval Allow balloon expression evaluation. Used with a
492 * debugger and for tooltips.
493 * Only for GUIs where it was implemented.
495 Property changes on: src/feature.h
496 ___________________________________________________________________
501 Property changes on: src/undo.c
502 ___________________________________________________________________
507 ===================================================================
508 --- src/buffer.c (.../vendor/vim/current) (revision 223)
509 +++ src/buffer.c (.../trunk/vim) (revision 223)
512 aubuflocal_remove(buf);
515 + gdb_buffer_free(gdb, buf);
520 @@ -5093,7 +5096,7 @@
521 newsign->lnum = lnum;
522 newsign->typenr = typenr;
523 newsign->next = next;
524 -#ifdef FEAT_NETBEANS_INTG
525 +#if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GDB)
526 newsign->prev = prev;
528 next->prev = newsign;
529 @@ -5139,12 +5142,12 @@
533 -#ifndef FEAT_NETBEANS_INTG /* keep signs sorted by lnum */
534 +#if !defined(FEAT_NETBEANS_INTG) && !defined(FEAT_GDB) /* keep signs sorted by lnum */
539 -#ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */
540 +#if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GDB) /* insert new sign at head of list for this lnum */
541 /* XXX - GRP: Is this because of sign slide problem? Or is it
542 * really needed? Or is it because we allow multiple signs per
543 * line? If so, should I add that feature to FEAT_SIGNS?
544 @@ -5161,7 +5164,7 @@
548 -#ifdef FEAT_NETBEANS_INTG /* insert new sign at head of list for this lnum */
549 +#if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GDB) /* insert new sign at head of list for this lnum */
550 /* XXX - GRP: See previous comment */
551 while (prev != NULL && prev->lnum == lnum)
553 @@ -5237,7 +5240,7 @@
557 -#ifdef FEAT_NETBEANS_INTG
558 +#if defined(FEAT_NETBEANS_INTG) || defined(FEAT_GDB)
560 next->prev = sign->prev;
562 @@ -5417,12 +5420,41 @@
565 signlist_T *sign; /* a sign in a b_signlist */
569 for (sign = curbuf->b_signlist; sign != NULL; sign = sign->next)
573 if (sign->lnum >= line1 && sign->lnum <= line2)
575 if (amount == MAXLNUM)
580 + else if (sign->lnum > line2)
581 + lnum += amount_after;
583 + /* Keep sign->lnum unchanged, but mark as changed the sign line and
584 + * the new line position if we had moved the line
585 + * (otherwise their highlighting may be scrolled along) */
586 + if (gdb_isrunning(gdb) && lnum != sign->lnum)
588 + changed_lines(sign->lnum, 0, sign->lnum + 1, 0);
589 + changed_lines(lnum, 0, lnum + 1, 0);
596 + for (sign = curbuf->b_signlist; sign != NULL; sign = sign->next)
598 + if (sign->lnum >= line1 && sign->lnum <= line2)
600 + if (amount == MAXLNUM)
603 sign->lnum += amount;
604 @@ -5430,6 +5462,7 @@
605 else if (sign->lnum > line2)
606 sign->lnum += amount_after;
610 #endif /* FEAT_SIGNS */
613 Property changes on: src/buffer.c
614 ___________________________________________________________________
619 ===================================================================
620 --- src/pty.c (.../vendor/vim/current) (revision 223)
621 +++ src/pty.c (.../trunk/vim) (revision 223)
623 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
626 -/* RCS_ID("$Id: pty.c,v 1.1 2004/06/13 20:04:27 vimboss Exp $ FAU") */
627 +/* RCS_ID("$Id$ FAU") */
632 Property changes on: src/pty.c
633 ___________________________________________________________________
638 Property changes on: src/misc1.c
639 ___________________________________________________________________
644 ===================================================================
645 --- src/main.c (.../vendor/vim/current) (revision 223)
646 +++ src/main.c (.../trunk/vim) (revision 223)
648 vim_tcl_init(params.argv[0]);
656 atexit(vim_mem_profile_dump);
658 @@ -1275,6 +1279,11 @@
659 apply_autocmds(EVENT_VIMLEAVEPRE, NULL, NULL, FALSE, curbuf);
663 + /* Before viminfo stuff to wipeout gdb buffer and remove from list */
668 if (*p_viminfo != NUL)
669 /* Write out the registers, history, marks etc, to the viminfo file */
671 Property changes on: src/main.c
672 ___________________________________________________________________
677 Property changes on: src/edit.c
678 ___________________________________________________________________
683 Property changes on: src/syntax.c
684 ___________________________________________________________________
689 ===================================================================
690 --- src/eval.c (.../vendor/vim/current) (revision 223)
691 +++ src/eval.c (.../trunk/vim) (revision 223)
693 static void f_foreground __ARGS((typval_T *argvars, typval_T *rettv));
694 static void f_function __ARGS((typval_T *argvars, typval_T *rettv));
695 static void f_garbagecollect __ARGS((typval_T *argvars, typval_T *rettv));
697 +static void f_gdb __ARGS((typval_T *argvars, typval_T *rettv));
699 static void f_get __ARGS((typval_T *argvars, typval_T *rettv));
700 static void f_getbufline __ARGS((typval_T *argvars, typval_T *rettv));
701 static void f_getbufvar __ARGS((typval_T *argvars, typval_T *rettv));
702 @@ -7499,6 +7502,9 @@
703 {"foreground", 0, 0, f_foreground},
704 {"function", 1, 1, f_function},
705 {"garbagecollect", 0, 1, f_garbagecollect},
707 + {"gdb", 1, 1, f_gdb},
709 {"get", 2, 3, f_get},
710 {"getbufline", 2, 3, f_getbufline},
711 {"getbufvar", 2, 2, f_getbufvar},
712 @@ -10326,7 +10332,26 @@
713 garbage_collect_at_exit = TRUE;
721 +f_gdb(argvars, rettv)
725 + char_u *cmd = get_tv_string(&argvars[0]);
728 + gdb_setwinput(gdb, (char_u *)""); /* open the window input-line */
730 + gdb_docmd(gdb, cmd); /* send cmd to gdb */
731 + rettv->vval.v_number = 1;
739 @@ -11479,6 +11504,9 @@
740 #if !defined(USE_SYSTEM) && defined(UNIX)
750 Property changes on: src/eval.c
751 ___________________________________________________________________
756 ===================================================================
757 --- src/normal.c (.../vendor/vim/current) (revision 223)
758 +++ src/normal.c (.../trunk/vim) (revision 223)
760 dont_scroll = FALSE; /* allow scrolling here */
763 +#if defined(FEAT_GDB) && defined(FEAT_CMDWIN)
764 + /* Launch the input-line window */
765 + if (cmdwin_type == 0 && gdb_iswinput(gdb))
773 * Get the command character from the user.
777 + c = gdb_safe_vgetc(gdb);
784 ++allow_keys; /* no mapping for nchar, but keys */
786 ++no_zero_mapping; /* don't map zero here */
789 + c = gdb_safe_vgetc(gdb);
794 LANGMAP_ADJUST(c, TRUE);
798 ++allow_keys; /* no mapping for nchar, but keys */
801 + c = gdb_safe_vgetc(gdb);
804 c = plain_vgetc(); /* get next character */
806 LANGMAP_ADJUST(c, TRUE);
808 * For 'g' get the next character now, so that we can check for
809 * "gr", "g'" and "g`".
813 + ca.nchar = gdb_safe_vgetc(gdb);
816 ca.nchar = plain_vgetc();
818 LANGMAP_ADJUST(ca.nchar, TRUE);
819 @@ -997,6 +1026,11 @@
825 + *cp = gdb_safe_vgetc(gdb);
831 @@ -1104,6 +1138,11 @@
832 while (enc_utf8 && lang && (c = vpeekc()) > 0
833 && (c >= 0x100 || MB_BYTE2LEN(vpeekc()) > 1))
837 + c = gdb_safe_vgetc(gdb);
841 if (!utf_iscomposing(c))
843 @@ -8668,6 +8707,10 @@
846 && cap->oap->regname == 0
848 + /* don't beep when opening gdb input-line window */
849 + && !gdb_iswinput(gdb)
853 if (cap->arg) /* TRUE for CTRL-C */
855 Property changes on: src/normal.c
856 ___________________________________________________________________
861 Property changes on: src/gui_gtk.c
862 ___________________________________________________________________
867 Property changes on: src/if_cscope.c
868 ___________________________________________________________________
873 Property changes on: src/gui_beval.c
874 ___________________________________________________________________
879 Property changes on: src/if_ruby.c
880 ___________________________________________________________________
885 Property changes on: src/if_cscope.h
886 ___________________________________________________________________
891 Property changes on: src/if_python.c
892 ___________________________________________________________________
897 Property changes on: src/gui_beval.h
898 ___________________________________________________________________
903 ===================================================================
904 --- src/proto.h (.../vendor/vim/current) (revision 223)
905 +++ src/proto.h (.../trunk/vim) (revision 223)
907 # include "if_xcmdsrv.pro"
915 * The perl include files pollute the namespace, therefore proto.h must be
916 * included before the perl include files. But then CV is not defined, which
918 Property changes on: src/proto.h
919 ___________________________________________________________________
924 Property changes on: src/gui_motif.c
925 ___________________________________________________________________
930 Property changes on: src/charset.c
931 ___________________________________________________________________
936 ===================================================================
937 --- src/Makefile (.../vendor/vim/current) (revision 223)
938 +++ src/Makefile (.../trunk/vim) (revision 223)
940 # WORKSHOP - Sun Visual Workshop interface. Only works with Motif!
941 #CONF_OPT_WORKSHOP = --enable-workshop
943 +# GDB - Include support for gdb
944 +CONF_OPT_GDB = --enable-gdb
946 # NETBEANS - NetBeans interface. Only works with Motif, GTK, and gnome.
947 # Motif version must have XPM libraries (see |workshop-xpm|).
948 # Uncomment this when you do not want the netbeans interface.
949 @@ -1414,12 +1417,14 @@
951 SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(MZSCHEME_SRC) \
952 $(PERL_SRC) $(PYTHON_SRC) $(TCL_SRC) $(RUBY_SRC) \
954 $(SNIFF_SRC) $(WORKSHOP_SRC) $(WSDEBUG_SRC)
956 TAGS_SRC = *.c *.cpp if_perl.xs
958 EXTRA_SRC = hangulin.c if_mzsch.c auto/if_perl.c if_perlsfio.c \
959 if_python.c if_tcl.c if_ruby.c if_sniff.c gui_beval.c \
960 + gdb.c clewn/gdb_lvl2.c clewn/gdb_lvl3.c clewn/misc.c clewn/obstack.c \
961 workshop.c wsdebug.c integration.c netbeans.c
963 # All sources, also the ones that are not configured
964 @@ -1429,6 +1434,7 @@
965 # checks more, but may not work well for checking a GUI that wasn't configured.
966 # The perl sources also don't work well with lint.
967 LINT_SRC = $(BASIC_SRC) $(GUI_SRC) $(HANGULIN_SRC) $(PYTHON_SRC) $(TCL_SRC) \
969 $(SNIFF_SRC) $(WORKSHOP_SRC) $(WSDEBUG_SRC) $(NETBEANS_SRC)
971 #LINT_SRC = $(ALL_SRC)
972 @@ -1489,6 +1495,7 @@
980 @@ -1544,6 +1551,7 @@
988 @@ -1577,6 +1585,7 @@
989 $(CONF_OPT_TCL) $(CONF_OPT_RUBY) $(CONF_OPT_NLS) \
990 $(CONF_OPT_CSCOPE) $(CONF_OPT_MULTIBYTE) $(CONF_OPT_INPUT) \
991 $(CONF_OPT_OUTPUT) $(CONF_OPT_GPM) $(CONF_OPT_WORKSHOP) \
993 $(CONF_OPT_SNIFF) $(CONF_OPT_FEAT) $(CONF_TERM_LIB) \
994 $(CONF_OPT_COMPBY) $(CONF_OPT_ACL) $(CONF_OPT_NETBEANS) \
995 $(CONF_ARGS) $(CONF_OPT_MZSCHEME) $(CONF_OPT_PLTHOME) \
996 @@ -2552,6 +2561,21 @@
997 objects/workshop.o: workshop.c
998 $(CCC) -o $@ workshop.c
1000 +objects/gdb.o: gdb.c
1001 + $(CCC) -o $@ gdb.c
1003 +objects/gdb_lvl2.o: clewn/gdb_lvl2.c
1004 + $(CCC) -o $@ clewn/gdb_lvl2.c
1006 +objects/gdb_lvl3.o: clewn/gdb_lvl3.c
1007 + $(CCC) -o $@ clewn/gdb_lvl3.c
1009 +objects/misc.o: clewn/misc.c
1010 + $(CCC) -o $@ clewn/misc.c
1012 +objects/obstack.o: clewn/obstack.c
1013 + $(CCC) -o $@ clewn/obstack.c
1015 objects/wsdebug.o: wsdebug.c
1016 $(CCC) -o $@ wsdebug.c
1018 @@ -2948,6 +2972,13 @@
1019 os_unix.h auto/osdef.h ascii.h keymap.h term.h macros.h option.h \
1020 structs.h regexp.h gui.h gui_beval.h proto/gui_beval.pro ex_cmds.h \
1021 proto.h globals.h farsi.h arabic.h version.h workshop.h
1022 +objects/gdb.o: gdb.c clewn/gdb.h clewn/misc.h auto/config.h vim.h feature.h
1023 +objects/gdb_lvl2.o: clewn/misc.h clewn/gdb_lvl2.c clewn/gdb_lvl3.c \
1024 + gdb.c clewn/gdb.h auto/config.h vim.h feature.h
1025 +objects/gdb_lvl3.o: clewn/misc.h clewn/gdb_lvl3.c gdb.c clewn/gdb.h\
1026 + auto/config.h vim.h feature.h
1027 +objects/misc.o: clewn/misc.c clewn/misc.h
1028 +objects/obstack.o: clewn/obstack.c clewn/obstack.h
1029 objects/wsdebug.o: wsdebug.c
1030 objects/integration.o: integration.c vim.h auto/config.h feature.h os_unix.h \
1031 auto/osdef.h ascii.h keymap.h term.h macros.h option.h structs.h \
1033 Property changes on: src/if_tcl.c
1034 ___________________________________________________________________
1039 Property changes on: src/wsdebug.c
1040 ___________________________________________________________________
1045 Property changes on: src/wsdebug.h
1046 ___________________________________________________________________
1051 Property changes on: src/nbdebug.c
1052 ___________________________________________________________________
1057 Property changes on: src/diff.c
1058 ___________________________________________________________________
1063 Property changes on: src/tag.c
1064 ___________________________________________________________________
1069 Property changes on: src/nbdebug.h
1070 ___________________________________________________________________
1075 Property changes on: src/misc2.c
1076 ___________________________________________________________________
1080 Index: src/config.h.in
1081 ===================================================================
1082 --- src/config.h.in (.../vendor/vim/current) (revision 223)
1083 +++ src/config.h.in (.../trunk/vim) (revision 223)
1085 /* Define if you want to include Sun Visual Workshop support. */
1086 #undef FEAT_SUN_WORKSHOP
1088 +/* Define if you want to include GDB support. */
1091 /* Define if you want to include NetBeans integration. */
1092 #undef FEAT_NETBEANS_INTG
1095 Property changes on: src/mbyte.c
1096 ___________________________________________________________________
1100 Index: src/gui_gtk_x11.c
1101 ===================================================================
1102 --- src/gui_gtk_x11.c (.../vendor/vim/current) (revision 223)
1103 +++ src/gui_gtk_x11.c (.../trunk/vim) (revision 223)
1104 @@ -6381,7 +6381,13 @@
1105 gui_mch_update(void)
1107 while (gtk_events_pending() && !vim_is_input_buf_full())
1110 + if (gdb_event(gdb)) /* got a gdb event */
1113 gtk_main_iteration_do(FALSE);
1118 @@ -6418,7 +6424,25 @@
1124 + * Callback function, used when data is available on the gdb file descriptor.
1131 + GdkInputCondition condition)
1133 + gdb_set_event(gdb, TRUE);
1135 + if (gtk_main_level() > 0)
1141 * GUI input routine called by gui_wait_for_chars(). Waits for a character
1142 * from the keyboard.
1143 * wtime == -1 Wait forever.
1144 @@ -6437,6 +6461,10 @@
1145 static int sniff_on = 0;
1146 static gint sniff_input_id = 0;
1149 + static int gdb_on = 0;
1150 + static gint gdb_input_id = 0;
1154 if (sniff_on && !want_sniff_request)
1155 @@ -6454,6 +6482,25 @@
1160 + /* Remove call back for previous gdb connection */
1161 + if (! gdb_allowed(gdb) && gdb_on)
1164 + gdk_input_remove(gdb_input_id);
1168 + /* A new gdb connection */
1169 + if (gdb_allowed(gdb) && !gdb_on)
1171 + /* Add gdb file descriptor to watch for available data in main loop. */
1172 + gdb_input_id = gdk_input_add(gdb_fd(gdb),
1173 + GDK_INPUT_READ, gdb_request_cb, NULL);
1180 /* this timeout makes sure that we will return if no characters arrived in
1181 @@ -6498,6 +6545,15 @@
1182 gtk_timeout_remove(timer);
1187 + if (wtime != 0L && gdb_allowed(gdb) && gdb_event(gdb))
1189 + if (timer != 0 && !timed_out)
1190 + gtk_timeout_remove(timer);
1194 } while (wtime < 0 || !timed_out);
1198 Property changes on: src/gui_gtk_x11.c
1199 ___________________________________________________________________
1203 Index: src/os_unix.c
1204 ===================================================================
1205 --- src/os_unix.c (.../vendor/vim/current) (revision 223)
1206 +++ src/os_unix.c (.../trunk/vim) (revision 223)
1208 static RETSIGTYPE sig_alarm __ARGS(SIGPROTOARG);
1209 static int sig_alarm_called;
1211 +#if defined(FEAT_GDB) && defined(SIGCHLD)
1212 +static RETSIGTYPE gdb_catch_sigchld __ARGS(SIGPROTOARG);
1214 static RETSIGTYPE deathtrap __ARGS(SIGPROTOARG);
1216 static void catch_int_signal __ARGS((void));
1219 {SIGPIPE, "PIPE", FALSE},
1221 +#if defined(FEAT_GDB) && defined(SIGCHLD)
1222 + {SIGCHLD, "CHLD", FALSE},
1224 {-1, "Unknown!", FALSE}
1227 @@ -341,6 +347,10 @@
1231 +#if defined(FEAT_GDB) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1232 + struct timeval start_tv;
1233 + gettimeofday(&start_tv, NULL);
1236 /* Check if window changed size while we were busy, perhaps the ":set
1237 * columns=99" command was used. */
1238 @@ -351,6 +361,21 @@
1240 while (WaitForChar(wtime) == 0) /* no character available */
1243 + if (gdb_event(gdb) && gdb_allowed(gdb))
1245 +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1246 + if ((wtime = gdb_process_output(gdb, wtime, (void *)&start_tv)) < 0)
1248 + /* guess we got interrupted halfway */
1249 + wtime = wtime / 2;
1251 + if ((wtime = gdb_process_output(gdb, wtime, NULL)) < 0)
1253 + return 0; /* launch input-line window */
1257 if (!do_resize) /* return if not interrupted by resize */
1260 @@ -363,8 +388,25 @@
1261 * flush all the swap files to disk.
1262 * Also done when interrupted by SIGWINCH.
1267 + while (WaitForChar(wtime) == 0)
1269 + if (gdb_event(gdb) && gdb_allowed(gdb))
1271 +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
1272 + if ((wtime = gdb_process_output(gdb, wtime, (void *)&start_tv)) < 0)
1274 + if ((wtime = gdb_process_output(gdb, wtime, NULL)) < 0)
1276 + return 0; /* launch input-line window */
1280 if (WaitForChar(p_ut) == 0)
1284 if (trigger_cursorhold() && maxlen >= 3
1285 && !typebuf_changed(tb_change_cnt))
1286 @@ -376,6 +418,10 @@
1292 + } /* while (WaitForChar(wtime) == 0) */
1297 @@ -387,6 +433,16 @@
1298 * we want to be interrupted by the winch signal
1303 + if (gdb_event(gdb) && gdb_allowed(gdb))
1305 + if (gdb_process_output(gdb, -1L, NULL) < 0)
1306 + return 0; /* launch input-line window */
1311 if (do_resize) /* interrupted by SIGWINCH signal */
1314 @@ -858,6 +914,30 @@
1318 +#if defined(FEAT_GDB) && defined(SIGCHLD)
1320 + * On SIGCHLD, note when gdb process is defunct or does not exist any more
1323 +gdb_catch_sigchld SIGDEFARG(sigarg)
1328 + if (sigarg == SIGCHLD && (pid = gdb_pid(gdb)) != -1)
1330 + wait_pid = waitpid(pid, NULL, WNOHANG);
1332 + if ((wait_pid == (pid_t)-1 && errno == ECHILD)
1333 + || wait_pid == pid)
1334 + gdb_set_sigchld(gdb, TRUE);
1337 + signal(SIGCHLD, (RETSIGTYPE (*)())gdb_catch_sigchld);
1342 #if (defined(HAVE_SETJMP_H) \
1343 && ((defined(FEAT_X11) && defined(FEAT_XCLIPBOARD)) \
1344 || defined(FEAT_LIBCALL))) \
1345 @@ -1203,6 +1283,13 @@
1349 + * Catch SIGCHLD to monitor gdb process state
1351 +#if defined(FEAT_GDB) && defined(SIGCHLD)
1352 + signal(SIGCHLD, (RETSIGTYPE (*)())gdb_catch_sigchld);
1356 * Arrange for other signals to gracefully shutdown Vim.
1358 catch_signals(deathtrap, SIG_ERR);
1359 @@ -4733,7 +4820,12 @@
1364 + struct pollfd fds[6];
1367 struct pollfd fds[5];
1370 # ifdef FEAT_XCLIPBOARD
1372 @@ -4794,7 +4886,23 @@
1377 + if (msec != 0L && gdb_allowed(gdb))
1379 + /* handle pending SIGCHLD from gdb */
1380 + if (gdb_sigchld(gdb))
1382 + gdb_set_event(gdb, TRUE);
1387 + fds[nfd].fd = gdb_fd(gdb);
1388 + fds[nfd].events = POLLIN;
1393 ret = poll(fds, nfd, towait);
1394 # ifdef FEAT_MZSCHEME
1395 if (ret == 0 && mzquantum_used)
1396 @@ -4802,6 +4910,27 @@
1401 + if (msec != 0L && gdb_allowed(gdb))
1403 + if (ret > 0 && fds[gdb_idx].revents & POLLIN)
1407 + gdb_set_event(gdb, TRUE);
1409 + gdb_set_event(gdb, FALSE);
1412 + /* EINTR poll error */
1413 + if (ret < 0 && gdb_sigchld(gdb) && !got_int)
1414 + gdb_set_event(gdb, TRUE);
1416 + /* an event: gdb's SIGCHLD or gdb data output */
1417 + if (gdb_event(gdb))
1423 sniff_disconnect(1);
1424 @@ -4928,7 +5057,24 @@
1429 + if (msec != 0L && gdb_allowed(gdb))
1431 + int fd = gdb_fd(gdb);
1433 + /* handle pending SIGCHLD from gdb */
1434 + if (gdb_sigchld(gdb))
1436 + gdb_set_event(gdb, TRUE);
1440 + FD_SET(fd, &rfds);
1447 /* Old VMS as v6.2 and older have broken select(). It waits more than
1448 * required. Should not be used */
1449 @@ -4950,6 +5096,27 @@
1454 + if (msec != 0L && gdb_allowed(gdb))
1456 + if (ret > 0 && FD_ISSET(gdb_fd(gdb), &rfds))
1460 + gdb_set_event(gdb, TRUE);
1462 + gdb_set_event(gdb, FALSE);
1465 + /* EINTR select error */
1466 + if (ret < 0 && gdb_sigchld(gdb) && ! got_int)
1467 + gdb_set_event(gdb, TRUE);
1469 + /* an event: gdb's SIGCHLD or gdb data output */
1470 + if (gdb_event(gdb))
1476 sniff_disconnect(1);
1478 Property changes on: src/os_unix.c
1479 ___________________________________________________________________
1484 Property changes on: src/fold.c
1485 ___________________________________________________________________
1489 Index: src/version.c
1490 ===================================================================
1491 --- src/version.c (.../vendor/vim/current) (revision 223)
1492 +++ src/version.c (.../trunk/vim) (revision 223)
1493 @@ -236,6 +236,11 @@
1494 #if !defined(USE_SYSTEM) && defined(UNIX)
1503 # ifdef DYNAMIC_GETTEXT
1506 Property changes on: src/version.c
1507 ___________________________________________________________________
1512 Property changes on: src/os_unix.h
1513 ___________________________________________________________________
1518 Property changes on: src/version.h
1519 ___________________________________________________________________
1524 Property changes on: src/keymap.h
1525 ___________________________________________________________________
1529 Index: src/ex_getln.c
1530 ===================================================================
1531 --- src/ex_getln.c (.../vendor/vim/current) (revision 223)
1532 +++ src/ex_getln.c (.../trunk/vim) (revision 223)
1533 @@ -723,6 +723,12 @@
1535 if (c == cedit_key || c == K_CMDWIN)
1538 + /* Set cmdfirstc before calling ex_window (up to now it is NUL:
1539 + * the input line does not have a '@' leading character) */
1540 + if (firstc == '@')
1541 + ccline.cmdfirstc = firstc;
1544 * Open a window to edit the command line (and history).
1546 @@ -6011,6 +6017,30 @@
1547 /* don't use a new tab page */
1551 + /* Split below the displayed gdb window */
1552 + if (gdb_iswinput(gdb) && (wp = gdb_window(gdb)) != NULL
1553 + && (wp = wp->w_next) != NULL)
1558 + curbuf = curwin->w_buffer;
1559 + topline = curwin->w_topline;
1561 + if (win_split((int)p_cwh, WSP_ABOVE) == FAIL)
1563 + curwin = old_curwin;
1564 + curbuf = old_curbuf;
1569 + /* Do not scroll the window below gdb window */
1570 + set_topline(wp, topline + p_cwh + STATUS_HEIGHT);
1574 /* Create a window for the command-line buffer. */
1575 if (win_split((int)p_cwh, WSP_BOT) == FAIL)
1577 @@ -6057,6 +6087,20 @@
1578 set_option_value((char_u *)"ft", 0L, (char_u *)"vim", OPT_LOCAL);
1582 + if (gdb_iswinput(gdb)) /* gdb window input-line */
1584 + add_map((char_u *)"<buffer> <C-Z> <C-Z><CR>", INSERT);
1585 + add_map((char_u *)"<buffer> <Tab> <C-Q><C-I><CR>", INSERT);
1586 + set_option_value((char_u *)"ft", 0L, (char_u *)"gdb", OPT_LOCAL);
1587 + set_option_value((char_u *)"fdc", 0L, NULL, OPT_LOCAL);
1589 + /* The window search-line does not have this: with a two lines history,
1590 + * the window shows an empty line at top */
1591 + curwin->w_valid = FALSE;
1595 /* Reset 'textwidth' after setting 'filetype' (the Vim filetype plugin
1596 * sets 'textwidth' to 78). */
1598 @@ -6180,6 +6224,10 @@
1599 cmdwin_result = Ctrl_C;
1603 + if (ccline.cmdfirstc == '@')
1604 + ccline.cmdfirstc = NUL;
1606 ccline.cmdlen = (int)STRLEN(ccline.cmdbuff);
1607 ccline.cmdbufflen = ccline.cmdlen + 1;
1608 ccline.cmdpos = curwin->w_cursor.col;
1610 Property changes on: src/ex_getln.c
1611 ___________________________________________________________________
1616 ===================================================================
1617 --- src/screen.c (.../vendor/vim/current) (revision 223)
1618 +++ src/screen.c (.../trunk/vim) (revision 223)
1619 @@ -5753,6 +5753,11 @@
1620 fillchar = fillchar_status(&attr, wp == curwin);
1622 get_trans_bufname(wp->w_buffer);
1624 + /* Replace fname with gdb window label */
1625 + gdb_label(gdb, wp->w_buffer, NameBuff, MAXPATHL);
1626 + trans_characters(NameBuff, MAXPATHL);
1629 len = (int)STRLEN(p);
1632 Property changes on: src/screen.c
1633 ___________________________________________________________________
1638 Property changes on: src/os_unixx.h
1639 ___________________________________________________________________
1644 Property changes on: src/arabic.c
1645 ___________________________________________________________________
1650 Property changes on: src/memline.c
1651 ___________________________________________________________________
1656 Property changes on: src/arabic.h
1657 ___________________________________________________________________
1661 Index: src/auto/configure
1662 ===================================================================
1663 --- src/auto/configure (.../vendor/vim/current) (revision 223)
1664 +++ src/auto/configure (.../trunk/vim) (revision 223)
1682 @@ -1465,6 +1468,7 @@
1683 --enable-rubyinterp Include Ruby interpreter.
1684 --enable-cscope Include cscope interface.
1685 --enable-workshop Include Sun Visual Workshop support.
1686 + --enable-gdb Include GDB support.
1687 --disable-netbeans Disable NetBeans integration support.
1688 --enable-sniff Include Sniff interface.
1689 --enable-multibyte Include multibyte editing support.
1690 @@ -5788,6 +5792,18 @@
1694 +echo "$as_me:$LINENO: checking --enable-gdb argument" >&5
1695 +echo $ECHO_N "checking --enable-gdb argument... $ECHO_C" >&6
1696 +# Check whether --enable-gdb or --disable-gdb was given.
1697 +if test "${enable_gdb+set}" = set; then
1698 + enableval="$enable_gdb"
1703 +echo "$as_me:$LINENO: result: $enable_gdb" >&5
1704 +echo "${ECHO_T}$enable_gdb" >&6
1706 { $as_echo "$as_me:$LINENO: checking --enable-workshop argument" >&5
1707 $as_echo_n "checking --enable-workshop argument... " >&6; }
1708 # Check whether --enable-workshop was given.
1709 @@ -10197,6 +10213,22 @@
1713 +if test "$enable_gdb" = "yes"; then
1714 + cat >>confdefs.h <<\_ACEOF
1718 + if test "x$GUITYPE" = "xNONE"; then
1719 + GDB_SRC="gdb.c clewn/gdb_lvl2.c clewn/gdb_lvl3.c clewn/misc.c clewn/obstack.c pty.c"
1720 + GDB_OBJ="objects/gdb.o objects/gdb_lvl2.o objects/gdb_lvl3.o objects/misc.o objects/obstack.o objects/pty.o"
1722 + GDB_SRC="gdb.c clewn/gdb_lvl2.c clewn/gdb_lvl3.c clewn/misc.c clewn/obstack.c"
1723 + GDB_OBJ="objects/gdb.o objects/gdb_lvl2.o objects/gdb_lvl3.o objects/misc.o objects/obstack.o"
1729 if test "$enable_workshop" = "yes" -a -n "$SKIP_MOTIF"; then
1730 { { $as_echo "$as_me:$LINENO: error: cannot use workshop without Motif" >&5
1731 $as_echo "$as_me: error: cannot use workshop without Motif" >&2;}
1733 Property changes on: src/auto
1734 ___________________________________________________________________
1746 Property changes on: src/gui_at_sb.c
1747 ___________________________________________________________________
1752 Property changes on: src/gui_gtk_f.c
1753 ___________________________________________________________________
1758 Property changes on: src/ops.c
1759 ___________________________________________________________________
1764 Property changes on: src/gui_at_sb.h
1765 ___________________________________________________________________
1770 Property changes on: src/gui_gtk_f.h
1771 ___________________________________________________________________
1776 Property changes on: src/if_xcmdsrv.c
1777 ___________________________________________________________________
1782 Property changes on: src/farsi.c
1783 ___________________________________________________________________
1788 Property changes on: src/search.c
1789 ___________________________________________________________________
1794 Property changes on: src/fileio.c
1795 ___________________________________________________________________
1800 ===================================================================
1801 --- src/window.c (.../vendor/vim/current) (revision 223)
1802 +++ src/window.c (.../trunk/vim) (revision 223)
1803 @@ -6053,6 +6053,10 @@
1804 # ifdef FEAT_QUICKFIX
1808 + /* not counting a gdb window */
1809 + || gdb_isbuffer(gdb, wp->w_buffer)
1813 return (count <= 1);
1815 Property changes on: src/window.c
1816 ___________________________________________________________________
1821 Property changes on: src/farsi.h
1822 ___________________________________________________________________
1826 Index: src/gui_x11.c
1827 ===================================================================
1828 --- src/gui_x11.c (.../vendor/vim/current) (revision 223)
1829 +++ src/gui_x11.c (.../trunk/vim) (revision 223)
1832 static void gui_x11_sniff_request_cb __ARGS((XtPointer closure, int *source, XtInputId *id));
1835 +static void gdb_request_cb __ARGS((XtPointer closure, int *source, XtInputId *id));
1837 static void gui_x11_check_copy_area __ARGS((void));
1838 #ifdef FEAT_CLIENTSERVER
1839 static void gui_x11_send_event_handler __ARGS((Widget, XtPointer, XEvent *, Boolean *));
1840 @@ -1181,7 +1184,22 @@
1846 + * Callback function, used when data is available on the gdb file descriptor.
1850 +gdb_request_cb (closure, source, id)
1851 + XtPointer closure;
1855 + gdb_set_event(gdb, TRUE);
1860 * End of call-back routines
1863 @@ -2834,7 +2852,13 @@
1864 desired = (XtIMAll);
1865 while ((mask = XtAppPending(app_context)) && (mask & desired)
1866 && !vim_is_input_buf_full())
1869 + if (gdb_event(gdb)) /* got a gdb event */
1872 XtAppProcessEvent(app_context, desired);
1877 @@ -2863,6 +2887,10 @@
1878 static int sniff_on = 0;
1879 static XtInputId sniff_input_id = 0;
1882 + static int gdb_on = 0;
1883 + static XtInputId gdb_input_id = 0;
1888 @@ -2881,6 +2909,25 @@
1893 + /* Remove call back for previous gdb connection */
1894 + if (! gdb_allowed(gdb) && gdb_on)
1897 + XtRemoveInput(gdb_input_id);
1901 + /* A new gdb connection */
1902 + if (gdb_allowed(gdb) && !gdb_on)
1904 + /* Add gdb file descriptor to watch for available data in main loop. */
1905 + gdb_input_id = XtAppAddInput(app_context, gdb_fd(gdb),
1906 + (XtPointer)XtInputReadMask, gdb_request_cb, 0);
1912 timer = XtAppAddTimeOut(app_context, (long_u)wtime, gui_x11_timer_cb,
1914 @@ -2920,6 +2967,15 @@
1915 XtRemoveTimeOut(timer);
1920 + if (wtime != 0L && gdb_allowed(gdb) && gdb_event(gdb))
1922 + if (timer != (XtIntervalId)0 && !timed_out)
1923 + XtRemoveTimeOut(timer);
1931 Property changes on: src/gui_x11.c
1932 ___________________________________________________________________
1937 Property changes on: src/integration.c
1938 ___________________________________________________________________
1943 Property changes on: src/ex_eval.c
1944 ___________________________________________________________________
1949 Property changes on: src/integration.h
1950 ___________________________________________________________________
1954 Index: src/globals.h
1955 ===================================================================
1956 --- src/globals.h (.../vendor/vim/current) (revision 223)
1957 +++ src/globals.h (.../trunk/vim) (revision 223)
1958 @@ -1189,6 +1189,10 @@
1959 extern cursorentry_T shape_table[SHAPE_IDX_COUNT];
1963 +EXTERN gdb_handle_T *gdb INIT(= NULL); /* gdb opaque handle */
1968 * Printer stuff shared between hardcopy.c and machine-specific printing code.
1970 Property changes on: src/globals.h
1971 ___________________________________________________________________
1976 ===================================================================
1977 --- src/gdb.c (.../vendor/vim/current) (revision 0)
1978 +++ src/gdb.c (.../trunk/vim) (revision 223)
1980 +/* vi:set ts=8 sts=4 sw=4:
1982 + * VIM - Vi IMproved by Bram Moolenaar
1983 + * gdb support by Xavier de Gaye
1985 + * Do ":help uganda" in Vim to read copying and usage conditions.
1986 + * Do ":help credits" in Vim to see a list of people who contributed.
1993 +#ifdef FEAT_GDB /* possibly undefined in feature.h */
1994 +# include "clewn/obstack.h"
1995 +# include "clewn/gdb.h"
1996 +# include "clewn/misc.h"
1999 +# include "pty.pro"
2002 +# ifdef HAVE_SYS_WAIT_H
2003 +# include <sys/wait.h>
2006 +# ifdef HAVE_FCNTL_H
2007 +# include <fcntl.h>
2010 +# if defined(HAVE_SYS_SELECT_H) && \
2011 + (!defined(HAVE_SYS_TIME_H) || defined(SYS_SELECT_WITH_SYS_TIME))
2012 +# include <sys/select.h>
2015 +# ifndef HAVE_SELECT
2016 +# ifdef HAVE_SYS_POLL_H
2017 +# include <sys/poll.h>
2019 +# ifdef HAVE_POLL_H
2025 +# ifdef HAVE_TERMIOS_H
2026 +# include <termios.h>
2028 +# include <termio.h>
2031 +/* sun's sys/ioctl.h redefines symbols from termio world */
2032 +# if defined(HAVE_SYS_IOCTL_H) && !defined(sun)
2033 +# include <sys/ioctl.h>
2036 +# define SCROLLOFF 6 /* min lines around frame highlite */
2037 +# define MAXMEM 64L /* 'maxmem' option */
2039 +/* Not allowed after ^O in INS REP mode or from the input-line window */
2040 +# define NOT_ALLOWED_MODE (restart_edit != 0 || cmdwin_type != 0)
2042 +/* storage for mtrace hooks */
2043 +# if defined(GDB_MTRACE) && defined(HAVE_MTRACE)
2044 +__ptr_t (*s_malloc) (size_t, const void *);
2045 +void (*s_free) (void *, const void *);
2046 +__ptr_t (*s_realloc) (void *, size_t, const void *);
2047 +# endif /* GDB_MTRACE */
2049 +static int module_state = -1; /* initial state (not OK, nor FAIL) */
2050 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2051 +static char_u *inputrc; /* readline inputrc file name */
2054 +/* The gdb keyword */
2058 + char_u *keyword; /* keyword */
2059 + char_u *tail; /* optional tail */
2060 + regprog_T *regprog; /* compiled regexp */
2063 +static token_T tokens[] = {
2064 + {CMD_DIR, (char_u *)"dir", (char_u *)"ectory", NULL},
2065 + {CMD_DETACH, (char_u *)"det", (char_u *)"ach", NULL},
2066 + {CMD_SHELL, (char_u *)"she", (char_u *)"ll", NULL},
2067 + {CMD_STEPI, (char_u *)"si", (char_u *)"", NULL},
2068 + {CMD_STEPI, (char_u *)"stepi", (char_u *)"", NULL},
2069 + {CMD_STEPI, (char_u *)"ni", (char_u *)"", NULL},
2070 + {CMD_STEPI, (char_u *)"nexti", (char_u *)"", NULL},
2071 + {CMD_EXECF, (char_u *)"fil", (char_u *)"e", NULL},
2072 + {CMD_EXECF, (char_u *)"ex", (char_u *)"ec-file", NULL},
2073 + {CMD_EXECF, (char_u *)"cor", (char_u *)"e-file", NULL},
2074 + {CMD_BREAK, (char_u *)"b", (char_u *)"reak", NULL},
2075 + {CMD_BREAK, (char_u *)"tb", (char_u *)"reak", NULL},
2076 + {CMD_BREAK, (char_u *)"hb", (char_u *)"reak", NULL},
2077 + {CMD_BREAK, (char_u *)"thb", (char_u *)"reak", NULL},
2078 + {CMD_DISPLAY, (char_u *)"disp", (char_u *)"lay", NULL},
2079 + {CMD_CREATEVAR, (char_u *)"cr", (char_u *)"eatevar", NULL},
2080 + {CMD_UP_SILENT, (char_u *)"up-", (char_u *)"silently", NULL},
2081 + {CMD_UP, (char_u *)"up", (char_u *)"", NULL},
2082 + {CMD_DOWN_SILENT,(char_u *)"down-", (char_u *)"silently", NULL},
2083 + {CMD_DOWN, (char_u *)"do", (char_u *)"wn", NULL},
2084 + {CMD_FRAME, (char_u *)"f", (char_u *)"rame", NULL},
2085 + {CMD_DISABLE, (char_u *)"disab", (char_u *)"le", NULL},
2086 + {CMD_DELETE, (char_u *)"del", (char_u *)"ete", NULL},
2087 + {CMD_SLECT_FRAME,(char_u *)"sel", (char_u *)"ect-frame", NULL},
2088 + {CMD_SYMF, (char_u *)"sy", (char_u *)"mbol-file", NULL},
2089 + {CMD_SYMF, (char_u *)"add-sy", (char_u *)"mbol-file", NULL},
2090 + {CMD_ANY, NULL, NULL, NULL}
2093 +/* The gdb pattern */
2095 + int id; /* pattern id */
2096 + char_u *str; /* string pattern */
2097 + regprog_T *regprog; /* compiled regexp */
2100 +static pattern_T patterns[] = {
2101 + {PAT_DIR, (char_u *)"^\\s*Source directories searched:\\s*\\(.*\\)$", NULL},
2102 + {PAT_CHG_ANNO, (char_u *)"^\\s*set\\s\\+an\\%[notate]\\s\\+.*$", NULL},
2103 + {PAT_ADD, (char_u *)"^0x0*\\(\\x\\+\\)\\>", NULL},
2104 + {PAT_PID, (char_u *)"^\\s*at\\%[tach] \\+\\([0-9]\\+\\) *$", NULL},
2105 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2106 + {PAT_SOURCE, (char_u *)"^\\s*\\([^:]*\\):\\([^:]*\\):[^:]*:[^:]*:0x0*\\(\\x\\+\\)$", NULL},
2107 + {PAT_QUERY, (char_u *)"^.*(y or n) \\=$", NULL},
2108 + {PAT_YES, (char_u *)"^\\s*\\(\\<y\\%[es]\\>\\)\\s*$", NULL},
2109 + {PAT_SFILE, (char_u *)"^Symbols from\\s*\"\\([^\"]\\+\\)", NULL},
2110 + {PAT_BP_CONT, (char_u *)"^\\s*\\(c\\)\\>\\|^\\s*\\(cont\\)\\%[inue]\\>", NULL},
2111 + {PAT_ASM_FUNC, (char_u *)"^\\(\\S\\{-1,}\\)\\%((.*)\\)* .*in section .text$", NULL},
2112 + {PAT_ASM_FUNC_P, (char_u *)"^.*<\\(\\S\\{-1,}\\)\\%(+\\d\\+\\)*>$", NULL},
2113 + {PAT_FRAME, (char_u *)"^#\\d\\+\\s\\+0x0*\\(\\x\\+\\)\\>", NULL},
2115 +# ifdef GDB_LVL2_SUPPORT
2116 + /* MUST add '.*' at end of each info (possibly last) breakpoint field
2117 + * pattern because GDB adds the hit count, in a new line, after
2118 + * printing the last field and within its annotation context */
2119 + {PAT_BP_ASM, (char_u *)"^<\\(\\S\\+\\)+\\d\\+>.*$\\|^<\\(\\S\\+\\)>.*$", NULL},
2120 + {PAT_BP_SOURCE, (char_u *)"^.\\{-}\\(\\S\\+\\):\\(\\d\\+\\).*$", NULL},
2121 + {PAT_DISPLAY, (char_u *)"^\\s*disp\\%[lay]\\s*$", NULL},
2122 + {PAT_DISPINFO, (char_u *)"^\\(\\d\\+\\):", NULL},
2123 + {PAT_CREATEVAR, (char_u *)"^\\s*cr\\%[eatevar]\\>\\s*\\(.*\\)$", NULL},
2125 +# ifdef GDB_LVL3_SUPPORT
2126 + {PAT_CRVAR_FMT, (char_u *)"^\\s*cr\\%[eatevar]\\>\\s*\\(/[tdxo]\\)\\{,1}\\>\\s*\\(.*\\)$", NULL},
2127 + {PAT_INFO_FRAME, (char_u *)"^Stack level \\(\\d\\+\\), frame at ", NULL},
2132 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2133 +/* gdb readline inputrc file content */
2134 +static char *readline[] = {
2135 + "set show-all-if-ambiguous on\n",
2136 + "set completion-query-items 20\n", /* max without prompting user */
2137 + "Control-u: unix-line-discard\n",
2142 +/* Gdb process mgmt */
2143 +# define GDB_STATE(i,s) (((i) != NULL) ? ((((gdb_T *)(i))->state) & (s)):FALSE)
2144 +static void gdb_abort __ARGS((void));
2145 +static int start_gdb_process __ARGS((gdb_T *, char_u *));
2146 +static int module_init __ARGS((void));
2147 +static void module_end __ARGS((void));
2148 +static void clear_gdb_T __ARGS((gdb_T *));
2149 +static int exec_gdb __ARGS((gdb_T *));
2151 +/* Window and buffer mgmt */
2152 +static win_T *ftowin __ARGS((char_u *));
2153 +static buf_T *buffer_create __ARGS((char_u *, int, int, int, char_u *));
2154 +static void cursor_atbot __ARGS((gdb_T *));
2155 +static int line_append __ARGS((gdb_T *, char_u *));
2158 +static void histdel __ARGS((char_u *));
2160 +/** Create gdb, return its handle */
2166 +# if defined(GDB_MTRACE) && defined(HAVE_MTRACE)
2170 + /* register an abort function for when allocating memory fails */
2171 + xatabort(gdb_abort);
2172 + obstack_alloc_failed_handler = gdb_abort;
2174 + gdb = (gdb_T *)xcalloc((unsigned)sizeof(gdb_T));
2175 + gdb->state = GS_INIT;
2176 + gdb->pid = (pid_t)-1;
2178 + return (gdb_handle_T *)gdb;
2185 +#if defined(GDB_MTRACE) && defined(HAVE_MTRACE)
2188 + fprintf(stderr, "\nvirtual memory exhausted\n");
2195 + gdb_handle_T **pgdb;
2199 + if (pgdb == NULL || (this = (gdb_T *)*pgdb) == NULL)
2202 + if (this->buf != NULL) /* wipe out the buffer */
2203 + (void)do_bufdel(DOBUF_WIPE, (char_u *)"", 1, 0, this->buf->b_fnum, TRUE);
2206 + module_end(); /* release module resources */
2207 + clear_gdb_T(this);
2210 +# if defined(GDB_MTRACE) && defined(HAVE_MTRACE)
2215 +/** Return TRUE when gdb is running */
2218 + gdb_handle_T *gdb;
2220 + return GDB_STATE(gdb, GS_UP);
2223 +/** Return gdb pty file descriptor */
2226 + gdb_handle_T *gdb;
2228 + return (gdb != NULL ? ((gdb_T *)gdb)->fd : -1);
2231 +/** Return gdb process id */
2234 + gdb_handle_T *gdb;
2236 + return (gdb != NULL ? ((gdb_T *)gdb)->pid : (pid_t)-1);
2239 +/** Return TRUE when buf is the gdb buffer */
2241 +gdb_isbuffer(gdb, buf)
2242 + gdb_handle_T *gdb;
2243 + buf_T *buf; /* buffer to check for */
2245 + return ((gdb != NULL && ((gdb_T *)gdb)->buf != NULL)
2246 + ? ((gdb_T *)gdb)->buf == buf : FALSE);
2249 +/** Return TRUE when gdb output may be processed from low level functions */
2252 + gdb_handle_T *gdb;
2254 + return (GDB_STATE(gdb, GS_UP) && GDB_STATE(gdb, GS_ALLOWED));
2257 +/** Return TRUE when a gdb event is pending */
2260 + gdb_handle_T *gdb;
2262 + return GDB_STATE(gdb, GS_EVENT);
2265 +/** Return TRUE when there is a pending SIGCHLD */
2268 + gdb_handle_T *gdb;
2270 + return GDB_STATE(gdb, GS_SIGCHLD);
2273 +/** Set or unset a gdb event */
2275 +gdb_set_event (gdb, set)
2276 + gdb_handle_T *gdb;
2277 + int set; /* TRUE when setting event */
2282 + ((gdb_T *)gdb)->state &= ~GS_EVENT;
2284 + ((gdb_T *)gdb)->state |= GS_EVENT;
2287 +/** Set or unset a SIGCHLD event */
2289 +gdb_set_sigchld (gdb, set)
2290 + gdb_handle_T *gdb;
2291 + int set; /* TRUE when setting SIGCHLD event */
2296 + ((gdb_T *)gdb)->state &= ~GS_SIGCHLD;
2298 + ((gdb_T *)gdb)->state |= GS_SIGCHLD;
2302 + * Entry point for safe_vgetc().
2303 + * Set a flag to prevent recursion and enable gdb to read its pseudo tty
2304 + * in the low level routines.
2305 + * Return safe_vgetc return value.
2308 +gdb_safe_vgetc(gdb)
2309 + gdb_handle_T *gdb;
2311 + gdb_T *this = (gdb_T *)gdb;
2316 + return safe_vgetc();
2318 + s_a = (this->state & GS_ALLOWED);
2320 + /* set state GS_ALLOWED TRUE when called from top level,
2321 + * not in visual mode and not in the input-line window */
2322 + if (this->recurse == 0 && cmdwin_type == 0 && !VIsual_active)
2324 + this->state |= GS_ALLOWED;
2328 + this->state &= ~GS_ALLOWED;
2331 + rc = safe_vgetc(); /* call it now */
2334 + this->state &= ~GS_ALLOWED;
2336 + this->state |= GS_ALLOWED;
2340 +/** Take note Vim is freeing a buffer */
2342 +gdb_buffer_free(gdb, buf)
2343 + gdb_handle_T *gdb;
2344 + buf_T *buf; /* buffer being freed */
2346 + gdb_T *this = (gdb_T *)gdb;
2347 + bpinfo_T *p, **pt;
2352 + if (this->buf == buf)
2355 + /* variables window buffer */
2356 + else if (this->var_buf == buf)
2358 + this->var_buf = NULL;
2360 + /* call mode specifice var_delete */
2361 + if (this->var_delete != NULL)
2362 + this->var_delete(this); /* delete all variables */
2367 + for (i = 0; i < this->pool.max; i++)
2368 + if (this->pool.buf[i] == buf)
2370 + this->pool.buf[i] = NULL;
2374 + /* remove in bpinfo list the records corresponding to the
2376 + * the signs themselves are supposed to be removed by Vim
2377 + * in free_buffer()*/
2378 + for (pt = &(this->bpinfo); *pt != NULL; )
2381 + if (p->buf == buf)
2383 + gdb_undefine_sign(p->typenr);
2384 + *pt = p->next; /* unlink record */
2393 +# define STL_GDB "gdb "
2394 +# define STL_SEP1 "- "
2395 +# define STL_SEP2 " ["
2396 +# define STL_TAIL "]"
2397 +/** Write gdb status line label in dst */
2399 +gdb_label(gdb, buf, dst, len)
2400 + gdb_handle_T *gdb;
2401 + buf_T *buf; /* stl's buffer */
2402 + char_u *dst; /* where to write the label */
2403 + size_t len; /* label max length */
2405 + gdb_T *this = (gdb_T *)gdb;
2409 +# define STLCPY(s) {\
2410 + l = (((s)!=NULL) ? STRLEN((s)):0);\
2411 + l = MIN(l,len-cnt-1); \
2412 + STRNCPY(dst+cnt,(s),l); \
2416 + /* a console window displaying gdb buffer */
2417 + if (this != NULL && this->buf == buf && (this->state & GS_UP)
2418 + && dst != NULL && len > 0)
2421 + if (this->sfile != NULL)
2424 + fname = gettail(this->sfile);
2429 + STLCPY(this->status);
2431 + *(dst + cnt) = NUL;
2435 +/** Send a cmd to gdb */
2437 +gdb_docmd(gdb, cmd)
2438 + gdb_handle_T *gdb;
2439 + char_u *cmd; /* gdb cmd */
2441 + gdb_T *this = (gdb_T *)gdb;
2443 + if (this == NULL || NOT_ALLOWED_MODE)
2447 + this->state &= ~GS_STARTED;
2448 + if (!(this->state & GS_UP) && start_gdb_process(this, cmd) == FAIL)
2451 + /* process first cmd later */
2452 + if (this->state & GS_STARTED)
2455 + /* pop up gdb console */
2456 + gdb_popup_console(this);
2458 + /* The next statement has the following purpose:
2459 + * When stepping by hitting continuously key 'I', the discarded command
2460 + * give_warning (see few lines below) may be permanently displayed losing
2461 + * thus all meaning: better to clear the cmd line before possibly
2462 + * outputing the msg. */
2463 + msg_clr_cmdline();
2465 + /* accept one cmd at a time, allow intr */
2466 + if (cmd != NULL && *cmd != NUL && *(cmd + STRLEN(cmd) - 1) == KEY_INTERUPT)
2467 + this->oob.state |= OS_INTR;
2468 + else if (this->oob.state & OS_CMD)
2470 + give_warning((char_u *)"GDB busy: command discarded, please retry", TRUE);
2474 + this->oob.idx = -1; /* needed when last oob was aborted with OS_QUITs */
2475 + this->oob.state |= OS_CMD;
2477 + /* call mode specific docmd */
2478 + if (this->gdb_docmd != NULL)
2479 + this->gdb_docmd(this, cmd);
2482 +/** Set the cmd to be inserted later in the input-line window */
2484 +gdb_setwinput(gdb, cmd)
2485 + gdb_handle_T *gdb;
2486 + char_u *cmd; /* cmd to insert */
2488 + gdb_T *this = (gdb_T *)gdb;
2490 + if (this == NULL || NOT_ALLOWED_MODE)
2494 + cmd = (char_u *)"";
2496 + if (STRCHR(cmd, (int)NL) != NULL) /* assert no NL in cmd */
2499 + xfree(this->winput_cmd);
2500 + this->winput_cmd = vim_strsave_escaped(cmd, (char_u *)"\"");
2503 +/** Return TRUE if we are opening the gdb input-line window */
2506 + gdb_handle_T *gdb;
2508 + return (gdb != NULL ? ((gdb_T *)gdb)->winput_cmd != NULL : FALSE);
2511 +/** Launch the input-line window */
2514 + gdb_handle_T *gdb;
2516 + gdb_T *this = (gdb_T *)gdb;
2517 + int s_silent = cmd_silent;
2518 + char_u *cedit = NULL;
2519 + char_u *cmd = NULL;
2520 + char_u *res = NULL;
2521 + char_u key[2] = {NUL, NUL};
2524 + char_u *q = NULL; /* initialized to please the compiler */
2527 + if (this == NULL || NOT_ALLOWED_MODE)
2530 + if (this->winput_cmd == NULL || !stuff_empty() || typebuf.tb_len != 0)
2533 + /* pop up gdb console */
2534 + if (this->state & GS_UP)
2535 + gdb_popup_console(this);
2537 + /* insert in typebuf: <C-F> . "a" . winput_cmd */
2538 + /* 'a' start insert mode */
2542 + gdb_cat(&p, (char_u *)"a");
2543 + gdb_cat(&p, this->winput_cmd);
2545 + if (ins_typebuf(p, REMAP_NONE, 0, TRUE, TRUE) == FAIL)
2553 + (void)get_option_value((char_u *)"cedit", NULL, &cedit, OPT_GLOBAL);
2554 + set_option_value((char_u *)"cedit", 0L, key, OPT_GLOBAL);
2556 + /* Launch the input-line window */
2557 + /* careful: must free cmd with vim_free */
2558 + cmd_silent = FALSE;
2559 + cmd = getcmdline_prompt((int)'@', NULL, 0, EXPAND_NOTHING, NULL);
2560 + cmd_silent = s_silent;
2561 + msg_didout = FALSE;
2563 + /* restore cedit */
2564 + if (cedit != NULL)
2566 + set_option_value((char_u *)"cedit", 0L, cedit, OPT_GLOBAL);
2569 + cursor_atbot(this);
2571 + /* Do not start gdb when interrupt */
2572 + if (!(this->state & GS_UP)
2573 + && (cmd == NULL || STRCHR(cmd, KEY_INTERUPT) != NULL))
2579 + /* User typed ^C^C: send an interrupt */
2582 + key[0] = KEY_INTERUPT;
2583 + gdb_docmd(gdb, key);
2585 + else /* Cleanup history */
2587 + /* p first word, q first white after last word */
2588 + trim = (char_u *)clewn_strsave((char *)cmd);
2589 + r = p = skipwhite(trim);
2591 + q = skiptowhite(r);
2593 + } while (*r != NUL);
2595 + if ((res = STRCHR(cmd, '\t')) != NULL)
2598 + *(res + 1) = NUL; /* trim after <Tab> */
2600 + else if ((res = STRCHR(cmd, KEY_INTERUPT)) != NULL)
2603 + *(res + 1) = NUL; /* trim after ^Z */
2605 + /* trim surrounding spaces for syntax highliting */
2606 + else if (trim != NULL && (p != trim || *q != NUL))
2612 + add_to_history(HIST_INPUT, p, FALSE, NUL);
2616 + FREE(this->winput_cmd);
2619 + gdb_docmd(gdb, cmd);
2626 + FREE(this->winput_cmd);
2630 + * Invoke parse_output and compute time left to wait for a character in
2631 + * the caller, mch_inchar.
2632 + * Return time left or -1 when mch_inchar must trigger the input-line window.
2635 +gdb_process_output(gdb, wtime, start)
2636 + gdb_handle_T *gdb;
2637 + long wtime; /* time left */
2638 + void *start; /* start time in mch_inchar */
2640 + gdb_T *this = (gdb_T *)gdb;
2641 +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
2642 + struct timeval * pstart = (struct timeval *)start;
2643 + struct timeval tv;
2647 + if (this != NULL && (this->state & GS_ALLOWED))
2649 + if (this->parse_output == NULL)
2650 + return (wtime > 0 ? wtime : 0L);
2652 + /* call mode specific parser */
2653 + this->state &= ~GS_ALLOWED; /* prevent recursion */
2654 + rc = this->parse_output(this);
2655 + this->state |= GS_ALLOWED;
2657 + this->state &= ~GS_EVENT;
2664 +# if defined(HAVE_GETTIMEOFDAY) && defined(HAVE_SYS_TIME_H)
2665 + /* compute new remaining time */
2666 + if (pstart != NULL)
2668 + gettimeofday(&tv, NULL);
2669 + wtime -= (tv.tv_sec - pstart->tv_sec) * 1000L
2670 + + (tv.tv_usec - pstart->tv_usec) / 1000L;
2671 + pstart->tv_sec = tv.tv_sec; /* reset start time */
2672 + pstart->tv_usec = tv.tv_usec;
2677 + /* estimated gdb processing is 10 msecs */
2682 + return (wtime > 0 ? wtime : 0L);
2685 +/* Start a gdb process; return OK when succcess, FAIL otherwise */
2687 +start_gdb_process(this, cmd)
2689 + char_u *cmd; /* the first gdb cmd */
2691 + char_u *res = NULL;
2695 + clear_gdb_T(this);
2697 + if (module_init() == OK && exec_gdb(this) == OK)
2699 + /* save first non empty cmd */
2702 + p = skipwhite(cmd);
2704 + this->firstcmd = (char_u *)clewn_strsave((char *)cmd);
2707 + /* create variables window buffer */
2708 + if (p_gvar != NULL && *p_gvar != NUL)
2709 + this->var_buf = buffer_create(p_gvar, TRUE, TRUE, TRUE, (char_u *)"gdbvar");
2711 + /* create pool of asm buffers */
2712 + this->pool.max = MIN(ABS(p_asm), ASM_MAX_BUFF);
2713 + this->pool.idx = 0;
2714 + for (i = 0; i < this->pool.max; i++)
2716 + gdb_cat(&res, (char_u *)ASM_BUF_NAME);
2717 + gdb_cat(&res, gdb_itoa(i + 1));
2719 + this->pool.buf[i] = buffer_create(res, FALSE, FALSE, FALSE, NULL);
2720 + this->pool.age[i] = ASM_OLD;
2723 + this->pool.last = i + 1;
2724 + cursor_atbot(this);
2726 + this->directories = (char_u *)clewn_strsave(",,"); /* path: current directory */
2733 + * Initialize this module: set inputrc file, define signs, compile regexp.
2734 + * Return OK when succcess, FAIL otherwise.
2739 + char_u *s_cpo = p_cpo;
2745 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2750 + if (module_state == -1)
2752 + module_state = FAIL; /* do it only once */
2754 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2755 + /* Set gdb readline inputrc file contents
2756 + * careful: must free inputrc with vim_free
2757 + * We don't know yet if we are going to use GDB/MI, so we need to
2758 + * setup inputrc just in case, even though it might never be used */
2759 + if ((inputrc = vim_tempname((int)'A')) != NULL
2760 + && (fd = mch_open((char *)inputrc, O_CREAT | O_RDWR | O_EXTRA, 0644)) >= 0)
2762 + for (p = readline; *p; p++)
2763 + write(fd, *p, strlen(*p));
2765 + vim_setenv((char_u *)"INPUTRC", inputrc);
2769 + /* define breakpoint and frame signs */
2770 + do_highlight((char_u *)"gdb_bp term=bold ctermbg=Blue ctermfg=Black guibg=Blue guifg=Black", 0, 0);
2771 + do_highlight((char_u *)"gdb_dbp term=bold ctermbg=Green ctermfg=Black guibg=Green guifg=Black", 0, 0);
2772 + do_highlight((char_u *)"gdb_fr term=bold ctermbg=DarkYellow ctermfg=Black guibg=DarkYellow guifg=Black", 0, 0);
2774 + /* We use for frame and phantom sign type numbers the same
2775 + * value as their sign numbers. They are respectively FRAME_SIGN
2776 + * and PHANTOM_SIGN */
2777 + eap.arg = (char_u *)clewn_strsave(
2778 + "define 1 linehl=gdb_fr text==> texthl=Search");
2782 + eap.arg = (char_u *)clewn_strsave(
2783 + "define 2 linehl=Normal text=.. texthl=NonText");
2787 + /* make sure no sign in use */
2788 + buf_delete_all_signs();
2790 + /* Compile patterns */
2791 + p_cpo = (char_u *)""; /* so that 'l' flag doesn't work */
2792 + for (pat = patterns; pat->str != NULL; pat++)
2793 + if ((pat->regprog = vim_regcomp(pat->str, TRUE)) == NULL)
2796 + /* Compile tokens */
2797 + for (tok = tokens; tok->keyword != NULL; tok++)
2799 + len = (tok->tail != NULL ? STRLEN(tok->tail) : 0);
2801 + /* pattern: '^\s*\(\<token\%[option]\>\).*$' */
2803 + gdb_cat(&pattern, (char_u *)"^\\s*\\(\\<");
2804 + gdb_cat(&pattern, tok->keyword);
2808 + gdb_cat(&pattern, (char_u *)"\\%[");
2809 + gdb_cat(&pattern, tok->tail);
2810 + gdb_cat(&pattern, (char_u *)"]");
2813 + gdb_cat(&pattern, (char_u *)"\\>\\).*$");
2815 + if ((tok->regprog = vim_regcomp(pattern, TRUE)) == NULL)
2823 + module_state = OK;
2827 + return module_state;
2830 +/* Release module resources */
2838 + module_state = -1;
2840 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2841 + if (inputrc != NULL)
2843 + mch_remove(inputrc);
2844 + vim_free(inputrc);
2849 + /* remove signs */
2850 + do_highlight((char_u *)"clear gdb_bp", 0, 0);
2851 + do_highlight((char_u *)"clear gdb_dbp", 0, 0);
2852 + do_highlight((char_u *)"clear gdb_fr", 0, 0);
2854 + /* make sure no sign in use */
2855 + buf_delete_all_signs();
2858 + eap.arg = (char_u *)clewn_strsave("undefine 1");
2862 + eap.arg = (char_u *)clewn_strsave("undefine 2");
2867 + /* patterns an tokens */
2868 + for (pat = patterns; pat->str != NULL; pat++)
2869 + if (pat->regprog != NULL)
2870 + FREE(pat->regprog);
2872 + for (tok = tokens; tok->keyword != NULL; tok++)
2873 + if (tok->regprog != NULL)
2874 + FREE(tok->regprog);
2877 +/* Initialize a gdb_T structure */
2884 + this->pid = (pid_t)-1;
2885 +#if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2888 + this->state = GS_INIT;
2889 + FREE(this->status);
2890 + this->recurse = 0;
2892 + this->cmd_type = CMD_ANY;
2893 +#if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2894 + this->cli_cmd.state = CS_START;
2895 + this->cli_cmd.cnt = 0;
2896 + FREE(this->cli_cmd.gdb);
2897 + FREE(this->cli_cmd.readline);
2898 + FREE(this->cli_cmd.echoed);
2901 + FREE(this->firstcmd);
2902 + FREE(this->winput_cmd);
2903 + FREE(this->directories);
2904 + FREE(this->sfile);
2906 +#if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2907 + this->note = ANO_NONE;
2908 + this->annoted = FALSE;
2909 + this->newline = FALSE;
2910 + FREE(this->annotation);
2914 + FREE(this->frame_pc);
2915 + FREE(this->oob_result);
2916 + FREE(this->asm_add);
2917 + FREE(this->asm_func);
2919 +#if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
2920 + this->bp_state = 0;
2921 + gdb_free_bplist(&(this->tmplist));
2923 + FREE(this->record);
2924 + this->cont = FALSE;
2925 + gdb_free_bplist(&(this->bpinfo));
2926 + this->frame_curlvl = -1;
2927 + this->frame_lnum = (linenr_T) -1;
2928 + FREE(this->frame_fname);
2931 + this->fr_buf = NULL;
2933 + this->oob.state = 0;
2934 + this->oob.idx = -1;
2936 + this->pool.hilite = FALSE;
2938 + /* free mode specific data within gdb_T */
2939 + if (this->clear_gdb_T != NULL)
2940 + this->clear_gdb_T(this);
2942 + this->oobfunc = NULL;
2943 + this->parse_output = NULL;
2944 + this->gdb_docmd = NULL;
2945 + this->var_delete = NULL;
2946 + this->clear_gdb_T = NULL;
2950 +/* Spawn a gdb process; return OK when sucess, FAIL otherwise */
2955 + char_u *err = NULL;
2956 + int fd = -1; /* slave pty file descriptor */
2957 + char *tty; /* pty name */
2959 +# ifdef HAVE_TERMIOS_H
2960 + struct termios tio;
2962 + struct termio tio;
2965 + /* process already running */
2966 + if (this->pid != (pid_t)-1 && waitpid(this->pid, NULL, WNOHANG) == 0)
2970 + if ((this->fd = OpenPTY(&tty)) < 0
2971 + || (fd = open(tty, O_RDWR|O_NOCTTY|O_EXTRA, 0)) < 0
2972 + || SetupSlavePTY(fd) == -1)
2974 + err = (char_u *)"Cannot open gdb pty";
2978 + /* Set terminal attributes */
2979 +# ifdef HAVE_TERMIOS_H
2980 + if (tcgetattr(fd, &tio) == 0)
2982 + if (ioctl(fd, TCGETA, &tio) >= 0)
2985 + tio.c_oflag &= ~ONLCR; /* don't map NL to CR-NL on output */
2986 + tio.c_cc[VINTR] = KEY_INTERUPT;
2987 +# ifdef HAVE_TERMIOS_H
2988 + if (tcsetattr(fd, TCSAFLUSH, &tio) != 0)
2990 + if (ioctl(fd, TCSETA, &tio) < 0)
2993 + err = (char_u *)"Cannot set gdb pty";
2999 + err = (char_u *)"Cannot get gdb pty";
3003 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
3004 +# if defined(TIOCGWINSZ) && defined(TIOCSWINSZ)
3006 + struct winsize win;
3008 + /* set tty height */
3009 + if (ioctl(fd, TIOCGWINSZ, &win) >= 0)
3011 + win.ws_row = LPP_LINES;
3012 + if (ioctl(fd, TIOCSWINSZ, &win) >= 0)
3013 + this->height = LPP_LINES;
3020 + if ((this->pid = fork()) == (pid_t)-1)
3022 + err = (char_u *)"Cannot fork gdb";
3026 + else if (this->pid == (pid_t)0)
3028 + /* Grab control of terminal (from `The GNU C Library' (glibc-2.3.1)) */
3031 + if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
3035 + char *fdname = ttyname(fd);
3037 + /* This might work (it does on Linux) */
3046 + newfd = open(fdname, O_RDWR);
3052 + close(0); dup(fd);
3053 + close(1); dup(fd);
3054 + close(2); dup(fd);
3061 + /* close all swap files: on Cygwin, Windows fail to unlink the swap
3062 + * files while there is still an open file descriptor held by
3063 + * another (child) process */
3064 + for (buf = firstbuf; buf != NULL; buf = buf->b_next)
3065 + if (buf->b_ml.ml_mfp != NULL
3066 + && buf->b_ml.ml_mfp->mf_fd >= 0)
3067 + close(buf->b_ml.ml_mfp->mf_fd);
3069 +# ifdef GDB_MI_SUPPORT
3072 + /* MI mi2 is available starting with GDB 6.0 */
3073 + execlp(p_gdp, p_gdp, "--interpreter=mi2", NULL);
3074 + _exit(EXIT_FAILURE);
3077 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
3078 + clewn_exec((char *)p_gdp);
3079 +# endif /* defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT) */
3081 + _exit(EXIT_FAILURE);
3087 + this->state |= GS_UP;
3088 + this->state |= GS_STARTED;
3090 +# ifdef GDB_MI_SUPPORT
3093 + if (gdb_setup_mi(this) != OK)
3095 + gdb_cat(&err, (char_u *)"Cannot start GDB program \"");
3096 + gdb_cat(&err, p_gdp);
3097 + gdb_cat(&err, (char_u *)"\" (MI)");
3103 + this->state = GS_INIT;
3110 +# if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
3111 + if (gdb_setup_cli(this) != OK)
3113 + this->state = GS_INIT;
3120 + this->state = GS_INIT;
3124 + if (this->fd >= 0)
3133 +# define CG_QUIT "quit\n"
3134 +# define CG_YES "yes\n"
3135 +# define CG_TERM "Terminated\n\n"
3136 +# define CG_SEP "####################################\n"
3137 +# define CG_POLL 100
3138 +/* Close gdb process */
3147 + if (this->state & GS_CLOSING) /* prevent recursive calls */
3149 + this->state |= GS_CLOSING;
3151 + this->syntax = TRUE; /* force syntax highlite */
3152 + gdb_write_buf(this, (char_u *)CG_TERM, TRUE);
3153 + gdb_write_buf(this, (char_u *)CG_SEP, TRUE);
3154 + this->syntax = FALSE;
3156 + if (this->buf != NULL)
3157 + close_windows(this->buf, FALSE);
3159 + buf_delete_all_signs();
3161 + /* wipe out variables window buffer */
3162 + if (this->var_buf != NULL)
3163 + (void)do_bufdel(DOBUF_WIPE, (char_u *)"", 1, 0, this->var_buf->b_fnum, TRUE);
3165 + /* wipe out asm buffers */
3166 + for (i = 0; i < this->pool.max; i++)
3167 + if (this->pool.buf[i] != NULL)
3168 + (void)do_bufdel(DOBUF_WIPE, (char_u *)"", 1, 0, this->pool.buf[i]->b_fnum, TRUE);
3170 + /* free breakpoints table */
3171 + gdb_free_bplist(&(this->bpinfo));
3173 + /* a) attempt to gracefully terminate gdb process
3174 + * b) if this fails, SIGTERM it
3175 + * c) if this fails, too bad, just return */
3176 + if (this->pid != (pid_t)-1)
3178 + pid = waitpid(this->pid, NULL, WNOHANG);
3180 + if ((pid == (pid_t)-1 && errno == ECHILD) || pid == this->pid)
3182 + else /* still running */
3184 + char c = KEY_INTERUPT;
3185 + int killed = FALSE;
3186 + char_u buf[MAX_BUFFSIZE];
3189 + /* a) write an interrupt followed by a 'quit' cmd */
3190 + write(this->fd, &c, 1);
3191 + if (gdb_read(this, buf, MAX_BUFFSIZE, 1000) >= 0)
3193 + write(this->fd, CG_QUIT, strlen(CG_QUIT));
3194 + while ((rc = gdb_read(this, buf, MAX_BUFFSIZE, 100)) > 0)
3198 + write(this->fd, CG_YES, strlen(CG_YES));
3202 + /* make sure gdb is terminated: poll for waitpid() */
3203 + for (t = 0; !killed; t += CG_POLL)
3205 + /* 1 second elapsed since start of polling for waitpid */
3209 + /* b) kill it now */
3210 + kill(this->pid, SIGTERM);
3215 + mch_delay(CG_POLL, TRUE);
3216 + pid = waitpid(this->pid, NULL, WNOHANG);
3217 + if ((pid == (pid_t)-1 && errno == ECHILD) || pid == this->pid)
3221 + MSG_ATTR(_("GDB terminated"), hl_attr(HLF_E));
3224 + gdb_redraw(curbuf); /* force redrawing */
3225 + this->state = GS_INIT;
3226 + this->pid = (pid_t)-1;
3229 +/* Highlite asm_add line; return TRUE when asm_add found in asm buffer */
3231 +gdb_as_frset(this, obs)
3233 + struct obstack *obs;
3235 + char_u *ptrn = NULL;
3236 + int first = this->pool.idx;
3241 + if (this->asm_func == NULL)
3244 + /* age asm buffers */
3245 + for (i = 0; i < this->pool.max; i++)
3246 + if (this->pool.age[i] < ASM_OLD)
3247 + this->pool.age[i]++;
3249 + if (this->asm_add != NULL)
3251 + obstack_strcat(obs, "^\\s*0x0*");
3252 + obstack_strcat0(obs, this->asm_add);
3253 + ptrn = (char_u *)obstack_finish(obs);
3258 + /* Search all asm buffers whose name start with this->asm_func
3260 + * Start with the current one. */
3267 + if (this->pool.buf[i] != NULL
3268 + && STRSTR(this->pool.buf[i]->b_fname, this->asm_func) != NULL
3269 + && !(this->pool.buf[i]->b_ml.ml_flags & ML_EMPTY)
3270 + && searchit(NULL, this->pool.buf[i], &pos,
3271 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
3273 + this->pool.idx = i;
3274 + this->pool.age[i] = 0;
3275 + this->pool.lnum = pos.lnum;
3277 + if (this->pool.hilite)
3278 + gdb_fr_set(this, NULL, NULL, obs);
3279 + else if ((win = gdb_btowin(this->pool.buf[i])) != NULL)
3280 + gdb_set_cursor(win, pos.lnum);
3282 + FREE(this->asm_add);
3285 + } while ((i = ++i % this->pool.max) != first);
3292 + * Highlight line within frame
3293 + * Return -1 when failing to load the buffer, 0 otherwise
3296 +gdb_fr_set(this, file, line, obs)
3300 + struct obstack *obs;
3302 + win_T *oldwin = curwin;
3303 + buf_T *buf = NULL;
3306 + /* Do not set frame hilite when this breakpoint has a 'commands'
3307 + * with a 'continue' statement */
3310 + this->cont = FALSE;
3314 + if (line == NULL) /* in asm window */
3316 + buf = this->pool.buf[this->pool.idx];
3317 + lnum = this->pool.lnum;
3319 + else /* in source file */
3322 + if (buf != NULL || file != NULL)
3324 + if (gdb_edit_file(this, buf, file, lnum, obs) != NULL)
3326 + /* MUST redraw the screen before calling update_debug_sign():
3327 + * update_debug_sign() invokes win_update()
3328 + * the screen might have been scrolled when Vim ask the
3329 + * user to confirm changes made to the previous buffer */
3330 + gdb_redraw(curwin->w_buffer);
3332 + gdb_fr_lite(this, curwin->w_buffer, lnum, obs);
3342 +/* Highlite frame */
3344 +gdb_fr_lite(this, buf, lnum, obs)
3346 + buf_T *buf; /* where to highlite */
3347 + linenr_T lnum; /* line number */
3348 + struct obstack *obs;
3350 + buf_T *disped = NULL;
3352 + if (obs) {} /* keep compiler happy */
3354 + if (buf == NULL || lnum <= 0)
3358 + * Remove previous frame sign:
3359 + * GDB sends ANO_FRAME_INVALID annotations whenever stepping, running, etc...
3360 + * and these annotations invoke gdb_fr_unlite() that turn off the previous frame sign.
3361 + * But when moving along the stack frame with GDB 'up', 'down', 'frame' commands,
3362 + * we don't get annotations and must turn off the previous frame sign.
3364 + if (this->fr_buf != NULL)
3365 + disped = gdb_unlite(FRAME_SIGN);
3367 + /* add new frame highlite */
3368 + buf_addsign(buf, FRAME_SIGN, lnum, FRAME_SIGN);
3369 + update_debug_sign(buf, lnum);
3371 + /* remove phantom highlite */
3372 + disped = gdb_unlite(PHANTOM_SIGN);
3374 + this->fr_buf = buf;
3375 + if (gdb_btowin(buf) != NULL)
3378 + gdb_redraw(disped); /* only when displayed */
3383 +gdb_fr_unlite(this)
3386 + buf_T *disped = NULL;
3387 + buf_T *buf = this->fr_buf;
3392 + this->fr_buf = NULL;
3394 + /* To avoid screen blinks: replace with phantom sign */
3395 + if (gdb_btowin(buf) != NULL && (lnum = BUFLASTL(buf)) > 0)
3397 + buf_addsign(buf, PHANTOM_SIGN, lnum, PHANTOM_SIGN);
3398 + update_debug_sign(buf, lnum);
3401 + disped = gdb_unlite(FRAME_SIGN);
3402 + gdb_redraw(disped); /* only when displayed */
3407 + * Return last displayed buffer that contained this sign.
3411 + int id; /* sign id */
3413 + buf_T *disped = NULL;
3417 + for (buf = firstbuf; buf != NULL; buf = buf->b_next)
3418 + if ((lnum = buf_delsign(buf, id)) != 0)
3420 + update_debug_sign(buf, lnum);
3421 + if (gdb_btowin(buf) != NULL)
3428 + * Define a breakpoint sign. There is one sign type per breakpoint
3429 + * sign in order to have breakpoints numbers as the sign text.
3430 + * Returns sign type number or -1 if error.
3433 +gdb_define_sign(id, enabled)
3434 + int id; /* breakpoint number */
3435 + int enabled; /* TRUE when breakpoint is enabled */
3438 + char_u text[NUMBUFLEN];
3444 + /* the sign text is two chars max */
3446 + STRCPY(text, gdb_itoa(id));
3449 + if ((r = id % 100) < 10)
3452 + STRCPY(text + 1, gdb_itoa(r));
3455 + STRCPY(text, gdb_itoa(r));
3458 + /* With id = 1 and enabled TRUE, build the following:
3459 + * "define 3 linehl=gdb_bp text=1 texthl=LineNr" */
3461 + gdb_cat(&(eap.arg), (char_u *)"define ");
3462 + gdb_cat(&(eap.arg), gdb_itoa(BP_SIGN_ID(id)));
3463 + gdb_cat(&(eap.arg), (char_u *)" linehl=");
3466 + gdb_cat(&(eap.arg), (char_u *)"gdb_bp");
3468 + gdb_cat(&(eap.arg), (char_u *)"gdb_dbp");
3470 + gdb_cat(&(eap.arg), (char_u *)" text=");
3471 + gdb_cat(&(eap.arg), text);
3472 + gdb_cat(&(eap.arg), (char_u *)" texthl=LineNr");
3476 + return BP_SIGN_ID(id);
3479 +/* Undefine a breakpoint sign */
3481 +gdb_undefine_sign(typenr)
3482 + int typenr; /* sign type number to undefine */
3491 + gdb_cat(&(eap.arg), (char_u *)"undefine ");
3492 + gdb_cat(&(eap.arg), gdb_itoa(typenr));
3498 +/** Return the (first) console window where is displayed gdb */
3501 + gdb_handle_T *gdb;
3503 + return (gdb != NULL ? gdb_btowin(((gdb_T *)gdb)->buf): NULL);
3506 +/* Return (first) window where buf is displayed */
3514 + for (win = firstwin; win != NULL; win = win->w_next)
3515 + if (win->w_buffer == buf)
3520 +/* Return (first) window where file fname is displayed */
3525 + buf_T *buf = NULL;
3528 + /* first make the name into a full path name
3529 + * force expansion, get rid of symbolic links */
3530 + if (fname != NULL && (name = FullName_save(fname, TRUE)) != NULL)
3532 + buf = buflist_findname(name);
3535 + return gdb_btowin(buf);
3538 +/* Pop up gdb console, load the buffer when first time */
3540 +gdb_popup_console(this)
3543 + win_T *oldwin = curwin;
3544 + char_u *name = NULL;
3550 + /* already displayed */
3551 + if (this->buf != NULL && gdb_btowin(this->buf) != NULL)
3554 + /* get a unique name */
3555 + if (this->buf == NULL &&
3556 + (! (this->state & GS_UP)
3557 + || (name = vim_tempname((int)'A')) == NULL))
3560 + /* get splitbelow and splitright options values */
3561 + (void) get_option_value((char_u *)"sb", &splitbelow, NULL, OPT_LOCAL);
3562 + (void) get_option_value((char_u *)"spr", &splitright, NULL, OPT_LOCAL);
3566 + flags = WSP_BOT; /* bottom */
3568 + flags = WSP_VERT | WSP_TOP; /* left */
3572 + flags = WSP_VERT | WSP_BOT; /* right */
3574 + flags = WSP_TOP; /* the default: top */
3577 + /* create new window */
3578 + if (win_split(p_pvh > 0 ? p_pvh : 0, flags) == FAIL)
3580 + vim_free(name); /* free name with vim_free */
3584 + if (this->buf == NULL)
3586 + p_mm = MAXMEM; /* buffer max virtual memory */
3587 + (void)do_ecmd(0, name, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
3590 + vim_free(name); /* free name with vim_free */
3591 + msg_clr_cmdline();
3592 + curwin->w_alt_fnum = 0; /* no alternate */
3593 + this->buf = curbuf;
3595 + /* set buffer local options
3596 + * wrap, linebreak, nomodifiable, nolist
3597 + * filetype=gdbvim - bufhidden=hide - buftype=nowrite */
3598 + set_option_value((char_u *)"wrap", 0L, NULL, OPT_LOCAL);
3599 + set_option_value((char_u *)"lbr", 1L, NULL, OPT_LOCAL);
3600 + set_option_value((char_u *)"ma", 0L, NULL, OPT_LOCAL);
3601 + set_option_value((char_u *)"list", 0L, NULL, OPT_LOCAL);
3602 + set_option_value((char_u *)"syn", 0L, (char_u *)"gdbvim", OPT_LOCAL);
3603 + set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
3604 + set_option_value((char_u *)"bt", 0L, (char_u *)"nowrite", OPT_LOCAL);
3605 + set_option_value((char_u *)"bl", 0L, NULL, OPT_LOCAL);
3607 + else if (this->buf != curbuf)
3609 + set_curbuf(this->buf, DOBUF_GOTO);
3611 + /* nobuflisted must be set each time it's displayed */
3612 + set_option_value((char_u *)"bl", 0L, NULL, OPT_LOCAL);
3615 + /* return to previous window */
3616 + if (win_valid(oldwin))
3623 +/* Create an assembly buffer */
3625 +buffer_create(name, wrap, modifiable, listed, syntax)
3626 + char_u *name; /* buffer name */
3627 + int wrap; /* TRUE when option 'wrap' is set */
3628 + int modifiable; /* TRUE when option 'modifiable' is set */
3629 + int listed; /* TRUE when option 'listed' is set */
3630 + char_u *syntax; /* buffer syntax */
3632 + win_T *oldwin = curwin;
3633 + buf_T *buf = NULL;
3637 + /* save window sizes */
3638 + win_size_save(&sizes);
3640 +# ifdef FEAT_AUTOCMD
3643 + /* create a tmp window */
3644 + if (win_split(0, WSP_BOT) == OK)
3646 + /* create the asm buffer empty */
3647 + (void)do_ecmd(0, NULL, NULL, NULL, ECMD_ONE, ECMD_HIDE, NULL);
3648 + gdb_as_setname(name);
3649 +# ifdef FEAT_AUTOCMD
3650 + /* allow autocommands for loading syntax */
3653 + set_option_value((char_u *)"wrap", (long)wrap, NULL, OPT_LOCAL);
3654 + set_option_value((char_u *)"ma", (long)modifiable, NULL, OPT_LOCAL);
3655 + set_option_value((char_u *)"bl", (long)listed, NULL, OPT_LOCAL);
3657 + if (syntax != NULL)
3658 + set_option_value((char_u *)"syn", 0L, syntax, OPT_LOCAL);
3660 + set_option_value((char_u *)"bt", 0L, (char_u *)"nofile", OPT_LOCAL);
3661 + set_option_value((char_u *)"swf", 0L, NULL, OPT_LOCAL);
3662 + set_option_value((char_u *)"list", 0L, NULL, OPT_LOCAL);
3663 + set_option_value((char_u *)"bh", 0L, (char_u *)"hide", OPT_LOCAL);
3664 +# ifdef FEAT_AUTOCMD
3667 + if (curwin != oldwin)
3672 + win_close(wp, FALSE);
3675 +# ifdef FEAT_AUTOCMD
3678 + win_size_restore(&sizes);
3683 +/* Set a unique buffer name */
3685 +gdb_as_setname(name)
3686 + char_u *name; /* buffer name */
3688 + char_u *res = NULL;
3689 + int s_t = p_title;
3694 + p_title = p_icon = FALSE;
3697 + buf = gdb_itoa(i);
3703 + gdb_cat(&res, name);
3704 + gdb_cat(&res, buf);
3705 + } while (setfname(curbuf, res, NULL, FALSE) == FAIL);
3713 + * Clear an asm buffer of its content and signs.
3714 + * Rename it to an asm generic name.
3717 +gdb_clear_asmbuf(this, buf)
3719 + buf_T *buf; /* asm buffer to clear */
3721 + buf_T *oldbuf = curbuf;
3722 + char_u *res = NULL;
3723 + bpinfo_T *p, **pt;
3731 + /* rename buffer if its name is not a generic name */
3732 + if ((buf->b_sfname == NULL || STRSTR(buf->b_sfname, ASM_BUF_NAME) != buf->b_sfname))
3734 + gdb_cat(&res, (char_u *)ASM_BUF_NAME);
3735 + gdb_cat(&res, gdb_itoa(this->pool.last++));
3736 + gdb_as_setname(res);
3740 + lnum = BUFLASTL(buf);
3741 + while (lnum-- > 0) /* clear buffer */
3742 + ml_delete(buf->b_ml.ml_line_count, FALSE);
3745 + /* remove all the buffer signs:
3747 + * their corresponding bpinfo record
3748 + * their corresponding sign type */
3749 + for (pt = &(this->bpinfo); *pt != NULL; )
3752 + if (p->buf == buf)
3754 + buf_delsign(buf, BP_SIGN_ID(p->id));
3755 + gdb_undefine_sign(p->typenr);
3756 + *pt = p->next; /* unlink record */
3763 + /* remove frame sign if present */
3764 + if (this->fr_buf == buf)
3766 + gdb_unlite(FRAME_SIGN);
3767 + this->fr_buf = NULL;
3771 +/* Put back gdb console's last line at bottom. */
3772 +/* needed after win_close messes up gdb topline when 'equalalways' on */
3777 + win_T *oldwin = curwin;
3780 + if ((win = gdb_btowin(this->buf)) != NULL)
3783 + curbuf = curwin->w_buffer;
3784 + scroll_cursor_bot(0, TRUE);
3785 + redraw_later(VALID);
3787 + curbuf = curwin->w_buffer;
3791 +/* Append line to gdb buffer */
3793 +line_append(this, line)
3795 + char_u *line; /* line to append */
3797 + linenr_T lnum = BUFLASTL(this->buf);
3798 + char_u *res = NULL;
3802 +# define LN_PREFIX " "
3803 + /* disable syntax highliting by prefixing with LN_PREFIX */
3804 + if (! this->syntax)
3806 + gdb_cat(&res, (char_u *)LN_PREFIX);
3807 + gdb_cat(&res, line);
3808 + if ((line = res) == NULL)
3812 + /* first line ever: remove empty line after the one just inserted */
3813 + if ((rc = ml_append(lnum, line, 0, 0)) == OK && lnum == 0)
3814 + ml_delete(this->buf->b_ml.ml_line_count, FALSE);
3816 + if ((win = gdb_btowin(this->buf)) != NULL)
3817 + redraw_win_later(win, NOT_VALID);
3823 +/* Append to/Replace last line in gdb buffer */
3825 +gdb_write_buf(this, chunk, add)
3827 + char_u *chunk; /* a chunk may contain one, many or no NL */
3828 + int add; /* TRUE when chunk is added */
3830 + win_T *oldwin = curwin;
3834 + int cnt; /* number of lines appended */
3836 + if (chunk == NULL || this->buf == NULL)
3840 + chunk = (char_u *)clewn_strsave((char *)chunk);
3842 + /* set curbuf to buf */
3843 + curbuf = this->buf;
3845 + /* delete last line */
3847 + ml_delete(this->buf->b_ml.ml_line_count, FALSE);
3849 + /* append to buffer line after line */
3851 + for (ptr = start = chunk; *ptr != NUL; ptr++)
3856 + line_append(this, start);
3862 + /* handle an empty line or last non NL terminated stuff */
3863 + if (start == chunk || *start != NUL)
3865 + line_append(this, start);
3869 + changed_lines(this->buf->b_ml.ml_line_count - cnt, 0,
3870 + this->buf->b_ml.ml_line_count, cnt);
3872 + /* window displayed */
3873 + if ((win = gdb_btowin(this->buf)) != NULL)
3875 + /* update top line */
3877 + curwin->w_cursor.lnum = this->buf->b_ml.ml_line_count;
3880 + /* status line changed */
3881 + curwin->w_redr_status = TRUE;
3885 + curbuf = curwin->w_buffer;
3890 + * Edit a file in a non-console window.
3891 + * Use buf if non NULL, otherwise fname using gdb source path to find the file.
3892 + * Return NULL if error, curwin otherwise.
3895 +gdb_edit_file(this, buf, fname, lnum, obs)
3897 + buf_T *buf; /* asm buffer to load */
3898 + char_u *fname; /* file name */
3899 + linenr_T lnum; /* line number */
3900 + struct obstack *obs;
3902 +#ifdef GDB_LVL3_SUPPORT
3903 + char_u * source_cur = this->lvl3.source_cur; /* GDB current source */
3904 + char_u * source_list = this->lvl3.source_list; /* GDB source list */
3906 + char_u * source_cur = NULL;
3907 + char_u * source_list = NULL;
3913 + if (obs) {} /* keep comiler happy */
3915 + if (buf == NULL && (fname == NULL || *fname == NUL))
3919 + need_mouse_correct = TRUE;
3922 + /* found a window where source is already displayed */
3923 + if ((win = gdb_btowin(buf)) != NULL || (win = ftowin(fname)) != NULL)
3925 + gdb_set_cursor(win, lnum);
3931 + /* use a non-console window */
3932 + if (curbuf == this->buf)
3933 + for (win = firstwin; win != NULL; win = win->w_next)
3934 + if (win->w_buffer != this->buf)
3945 + /* get the first existing full path name in GDB source directories
3946 + * matching this name */
3947 + if ((fpn = (char_u *)get_fullpath((char *)fname, (char *)this->directories,
3948 + (char *)source_cur, (char *)source_list, obs)) == NULL)
3953 + (void)do_ecmd(0, fpn, NULL, NULL, lnum,
3954 + (P_HID(curbuf) ? ECMD_HIDE : 0) + ECMD_OLDBUF, curwin);
3956 + else if (buf != curbuf)
3957 + set_curbuf(buf, DOBUF_GOTO);
3959 + /* asm buffers are not listed */
3960 + if (buf != NULL && buf == curbuf)
3961 + for (i = 0; i < this->pool.max; i++)
3962 + if (this->pool.buf[i] == buf)
3964 + set_option_value((char_u *)"bl", 0L, NULL, OPT_LOCAL);
3968 + if (win_valid(win))
3970 + gdb_set_cursor(win, lnum);
3978 +/* Set cursor to lnum with at least SCROLLOFF lines around it */
3980 +gdb_set_cursor(win, lnum)
3984 + win_T *oldwin = curwin;
3990 + curbuf = curwin->w_buffer;
3992 + curwin->w_cursor.lnum = lnum;
3993 + curwin->w_cursor.col = 0;
3996 + if (p_so < SCROLLOFF )
4000 + win->w_redr_status = TRUE;
4004 + curbuf = curwin->w_buffer;
4008 +/* Display a cmd line busy msg */
4013 + static char *prop[] = { "/", "-", "\\", "|" };
4014 + static char busy[IOSIZE];
4017 + /* set busy string */
4020 + STRNCPY(busy, str, IOSIZE - 1);
4021 + busy[IOSIZE - 1] = NUL;
4025 + msg_scroll = FALSE;
4027 + msg_outtrans((char_u *)busy);
4028 + msg_puts((char_u *)" [");
4029 + msg_puts((char_u *)prop[(++cnt % 4)]);
4030 + msg_puts((char_u *)"]");
4036 +/* Set status and and mark stl dirty */
4038 +gdb_status(this, status, obs)
4040 + char_u *status; /* gdb status */
4041 + struct obstack *obs;
4045 + if (obs) {} /* keep comiler happy */
4047 + xfree(this->status);
4048 + this->status = (char_u *)clewn_strsave((char *)status);
4049 + if ((win = gdb_btowin(this->buf)) != NULL)
4050 + win->w_redr_status = TRUE;
4053 +/* Update screen when buf is displayed */
4054 +/* needed only from low level functions, not elsewhere */
4059 + int s_r = RedrawingDisabled;
4066 + for (win = firstwin; win != NULL; win = win->w_next)
4067 + if (win->w_buffer == buf)
4069 + RedrawingDisabled = 0;
4072 + RedrawingDisabled = s_r;
4075 + /* reset cursor */
4083 +/* Do the OOB_COMPLETE part of an oob cmd and send the next one */
4085 +gdb_oob_send(this, obs)
4087 + struct obstack *obs;
4089 + int keep = FALSE; /* when TRUE, do not switch to next oob function */
4091 + int *pi = &(this->oob.idx);
4092 + int s_a = (this->state & GS_ALLOWED);
4094 + /* prevent recursive calls to parse_output() since breakpoint
4095 + * or frame highlighting may cause Vim to query the user when
4096 + * changes have been made in the previous buffer */
4097 + this->state &= ~GS_ALLOWED;
4099 + if (this->oobfunc == NULL)
4104 + this->oob.state &= ~OS_INTR;
4105 + if (this->oob.state & OS_QUIT)
4109 + if (*pi >= 0 && (this->oobfunc)[*pi].oob != NULL) /* assert != NULL */
4111 + if ((this->oobfunc)[*pi].oob(this, OOB_COMPLETE, NULL, obs) != NULL)
4114 + if (this->oob.state & OS_QUIT)
4121 + while ((this->oobfunc)[*pi].oob != NULL && !(this->oob.state & OS_INTR))
4123 + if ((res = (this->oobfunc)[*pi].oob(this, OOB_CMD, NULL, obs)) != NULL)
4125 + this->oob.cnt = 0;
4127 + /* send the command to GDB */
4128 + write(this->fd, res, strlen(res));
4130 + this->state &= ~GS_ALLOWED;
4132 + this->state |= GS_ALLOWED;
4141 + this->oob.state &= ~OS_CMD;
4142 + this->oob.state &= ~OS_QUIT;
4144 + this->state &= ~GS_ALLOWED;
4146 + this->state |= GS_ALLOWED;
4149 +/* Receive out of band response to idx cmd */
4151 +gdb_oob_receive(this, chunk, obs)
4153 + char_u *chunk; /* response (possibly incomplete) */
4154 + struct obstack *obs;
4156 + char_u *res = NULL;
4157 + int s_a = (this->state & GS_ALLOWED);
4159 + /* prevent recursive calls to parse_output() since breakpoint
4160 + * or frame highlighting may cause Vim to query the user when
4161 + * changes have been made in the previous buffer */
4162 + this->state &= ~GS_ALLOWED;
4164 + if (this->oobfunc == NULL)
4167 + if(IS_OOBACTIVE(this))
4169 + /* silently discard when interrupted */
4170 + if (!(this->oob.state & OS_INTR) && chunk != NULL)
4172 + if (this->parser != PS_PREPROMPT && this->parser != PS_PROMPT
4173 + && (this->oobfunc)[this->oob.idx].oob != NULL) /* assert != NULL */
4176 + (void)(this->oobfunc)[this->oob.idx].oob(this, OOB_COLLECT, chunk, obs);
4178 + this->state &= ~GS_ALLOWED;
4180 + this->state |= GS_ALLOWED;
4185 + /* keep the last prompt */
4186 + if (this->parser == PS_PREPROMPT)
4188 + gdb_cat(&res, this->line);
4189 + gdb_cat(&res, chunk);
4190 + xfree(this->line);
4195 + this->state &= ~GS_ALLOWED;
4197 + this->state |= GS_ALLOWED;
4201 + * Fill up buff with a NUL terminated string of max size - 1 bytes from gdb.
4202 + * Return bytes read count, -1 if error or zero for nothing to read.
4205 +gdb_read(this, buff, size, wtime)
4207 + char_u *buff; /* where to write */
4208 + int size; /* buff size */
4209 + int wtime; /* msecs time out, -1 wait forever */
4213 +# ifndef HAVE_SELECT
4214 + struct pollfd fds;
4216 + fds.fd = this->fd;
4217 + fds.events = POLLIN;
4219 + struct timeval tv;
4220 + struct timeval start_tv;
4224 + FD_SET(this->fd, &rfds);
4226 +# ifdef HAVE_GETTIMEOFDAY
4228 + gettimeofday(&start_tv, NULL);
4232 + if (size <= 0 || buff == NULL || !(this->state & GS_UP))
4235 + /* make sure there is some data to read */
4238 + if (this->state & GS_SIGCHLD)
4241 +# ifndef HAVE_SELECT
4242 + if ((rc = poll(&fds, 1, wtime)) > 0)
4246 + tv.tv_sec = wtime / 1000;
4247 + tv.tv_usec = (wtime % 1000) * (1000000/1000);
4250 + if ((rc = select(this->fd + 1, &rfds, NULL, NULL, (wtime >= 0) ? &tv : NULL)) > 0)
4254 + if (rc == -1 && errno == EINTR)
4258 + /* compute remaining wait time */
4259 +# if ! defined(HAVE_SELECT) || ! defined(HAVE_GETTIMEOFDAY)
4260 + /* guess: interrupted halfway, gdb processing 10 msecs */
4261 + wtime = wtime / 2 - 10L;
4263 + gettimeofday(&tv, NULL);
4264 + wtime -= (tv.tv_sec - start_tv.tv_sec) * 1000L
4265 + + (tv.tv_usec - start_tv.tv_usec) / 1000L;
4277 + /* read the data */
4278 + if ((len = read(this->fd, (char *)buff, size - 1)) < 0)
4288 +/* Free a bpinfo_T list and set address referenced by plist to NULL */
4290 +gdb_free_bplist (plist)
4291 + bpinfo_T ** plist;
4293 + bpinfo_T *p, *next;
4295 + if (plist == NULL)
4298 + for (p = *plist; p != NULL; p = next)
4300 + gdb_undefine_sign(p->typenr);
4308 +/* Remove str from input history */
4311 + char_u *str; /* string to remove */
4316 + if (str != NULL && (res = vim_strsave_escaped(str, (char_u *)"\\")) != NULL)
4318 + /* nomagic: only the backslash has a special meaning */
4320 + gdb_cat(&pat, (char_u *)"\\V\\^");
4321 + gdb_cat(&pat, res);
4322 + gdb_cat(&pat, (char_u *)"\\$");
4324 + (void)del_history_entry(HIST_INPUT, pat);
4331 +/* Get the GDB command type */
4333 +gdb_cmd_type(this, cmd)
4337 + regmatch_T regmatch;
4340 + regmatch.rm_ic = FALSE; /* always match case */
4341 + this->cmd_type = CMD_ANY;
4342 + for (tok = tokens; tok->keyword != NULL; tok++)
4343 + if ((regmatch.regprog = tok->regprog) != NULL
4344 + && vim_regexec(®match, cmd, (colnr_T)0))
4346 + this->cmd_type = tok->type;
4352 + * Append src to string pointed to by pdest or copy src to a new allocated
4353 + * string when *pdest is NULL.
4354 + * *pdest is reallocated to make room for src.
4355 + * Append an empty string when src is NULL.
4358 +gdb_cat(pdest, src)
4359 + char_u **pdest; /* string address to append to */
4360 + char_u *src; /* string to append */
4362 + int ldest = (*pdest != NULL ? STRLEN(*pdest) : 0);
4363 + int lsrc = (src != NULL ? STRLEN(src) : 0);
4366 + if (lsrc != 0 || *pdest == NULL)
4368 + res = (char_u *)xmalloc(ldest + lsrc + 1);
4379 + STRCPY(res, *pdest);
4380 + STRCAT(res, src); /* assert src != NULL */
4389 + * Return an allocated string that is the sub-match indexed by subid ([0-9])
4390 + * using compiled pattern id.
4391 + * Return NULL if str does not match (or no such sub-match in pattern).
4394 +gdb_regexec(str, id, subid, obs)
4395 + char_u *str; /* string to match against */
4396 + int id; /* pattern id */
4397 + int subid; /* sub-match index */
4398 + struct obstack *obs;/* obstack to use for allocating memory */
4401 + regmatch_T regmatch;
4403 + if (str == NULL || *str == NUL || subid < 0 || subid > 9)
4406 + for (pat = patterns; pat->str != NULL; pat++)
4407 + if (pat->id == id)
4409 + regmatch.rm_ic = FALSE; /* always match case */
4410 + if ((regmatch.regprog = pat->regprog) != NULL
4411 + && vim_regexec(®match, str, (colnr_T)0)
4412 + && regmatch.startp[subid] != NULL)
4415 + return (char_u *)obstack_copy0(obs, regmatch.startp[subid],
4416 + (int)(regmatch.endp[subid] - regmatch.startp[subid]));
4418 + return (char_u *)clewn_strnsave((char *)regmatch.startp[subid],
4419 + (int)(regmatch.endp[subid] - regmatch.startp[subid]));
4426 +/* Return an integer as a string */
4429 + int i; /* integer to stringify */
4431 + static char buf[NUMBUFLEN];
4433 + sprintf(buf, "%ld", (long)i);
4434 + return (char_u *)buf;
4436 +#endif /* FEAT_GDB */
4438 Property changes on: src/gdb.c
4439 ___________________________________________________________________
4444 Property changes on: src
4445 ___________________________________________________________________
4455 diff -c --new-file old/clewn/gdb.h src/clewn/gdb.h
4456 *** old/clewn/gdb.h 1970-01-01 01:00:00.000000000 +0100
4457 --- src/clewn/gdb.h 2007-07-21 18:35:40.000000000 +0200
4461 + /* vi:set ts=8 sts=4 sw=4:
4463 + * Copyright (C) 2004 Xavier de Gaye.
4465 + * This program is free software; you can redistribute it and/or modify
4466 + * it under the terms of the GNU General Public License as published by
4467 + * the Free Software Foundation; either version 2, or (at your option)
4468 + * any later version.
4470 + * This program is distributed in the hope that it will be useful,
4471 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4472 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4473 + * GNU General Public License for more details.
4475 + * You should have received a copy of the GNU General Public License
4476 + * along with this program (see the file COPYING); if not, write to the
4477 + * Free Software Foundation, Inc.,
4478 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
4480 + * $Id: gdb.h 148 2007-07-21 16:35:40Z xavier $
4486 + #define obstack_chunk_alloc malloc
4487 + #define obstack_chunk_free free
4488 + #define obstack_strsave(o,s) (char_u *)obstack_copy0((o), (s), STRLEN((s)))
4489 + #define obstack_strcat(o,s) \
4490 + ( (s) ? obstack_grow((o), (s), STRLEN((s))) : 0)
4491 + #define obstack_strcat0(o,s) \
4493 + ? obstack_grow0((o), (s), STRLEN((s))) \
4494 + : obstack_grow0((o), "", 0))
4496 + #define GDB_LVL2_SUPPORT
4497 + #define GDB_LVL3_SUPPORT
4498 + /*#define GDB_MI_SUPPORT */
4500 + /* |+gdb| modes */
4501 + #define GDB_MODE_LVL2 1 /* CLI with annotations level 2 */
4502 + #define GDB_MODE_LVL3 2 /* CLI with annotations level 3 and GDB/MI */
4503 + #define GDB_MODE_MI 3 /* GDB/MI */
4505 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4507 + * GDB does not send ANO_BP_INVALID annotation when hitting a breakpoint
4508 + * that has been 'enable once'.
4509 + * Undefine BP_INVALID_ANO_MISSING after GDB fixes this
4511 + # define BP_INVALID_ANO_MISSING
4514 + #define KEY_INTERUPT Ctrl_Z /* interrupt */
4515 + #define MAX_BUFFSIZE 1024
4517 + /* The breakpoint info record structure */
4518 + typedef struct bpinfo_struct bpinfo_T;
4520 + struct bpinfo_struct
4522 + int id; /* breakpoint number */
4523 + int typenr; /* sign type number, for Clewn: sequence sign type number in this buffer */
4524 + #ifdef BP_INVALID_ANO_MISSING
4525 + int disposition; /* TRUE when keep, FALSE when disabled */
4527 + int enabled; /* TRUE when enabled */
4528 + int cont; /* TRUE when 'commands' includes continue */
4530 + buf_T *buf; /* breakpoint buffer */
4532 + int buf; /* Clewn buffer number */
4533 + int typenr_en; /* enabled breakpoint sequence number */
4534 + int typenr_dis; /* disabled breakpoint sequence number */
4536 + linenr_T lnum; /* breakpoint line number */
4540 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4541 + /* Annotation types */
4542 + # define ANO_NONE 0
4543 + # define ANO_ANY 1 /* some unrecognized annotation */
4545 + /* level 2 and level 3 annotations */
4546 + # define ANO_PREPROMPT 101
4547 + # define ANO_PROMPT 102
4548 + # define ANO_POSTPROMPT 103
4549 + # define ANO_PRECMDS 104
4550 + # define ANO_CMDS 105
4551 + # define ANO_PREOVERLOAD 106
4552 + # define ANO_OVERLOAD 107
4553 + # define ANO_PREQUERY 108
4554 + # define ANO_QUERY 109
4555 + # define ANO_PREPMT_FORMORE 110
4556 + # define ANO_PMT_FORMORE 111
4557 + # define ANO_POSTPMT_FORMORE 112
4558 + # define ANO_QUIT 113
4559 + # define ANO_ERROR_BEG 114
4560 + # define ANO_FRAME_INVALID 115
4561 + # define ANO_BP_INVALID 116
4562 + # define ANO_STARTING 117
4563 + # define ANO_STOPPED 118
4564 + # define ANO_EXITED 119
4565 + # define ANO_SIGNALLED 120
4566 + # define ANO_BREAKPOINT 121
4567 + # define ANO_SOURCE 122
4569 + # define KEY_KILL Ctrl_U /* readline 'unix-line-discard' */
4570 + # define LPP_LINES 500 /* large output interruption interval */
4572 + /* Command completion states */
4573 + # define CS_START 0
4574 + # define CS_PENDING 1
4575 + # define CS_CHOICE 2
4576 + # define CS_DONE 3
4577 + # define CS_QUERY 4
4579 + /* The gdb CLI cmd */
4582 + int state; /* cmd completion state */
4583 + int cnt; /* lines output by gdb since last cmd */
4584 + char_u *gdb; /* partial cmd sent to gdb */
4585 + char_u *readline; /* gdb readline content */
4586 + char_u *echoed; /* echoed cmd */
4589 + /* breakpoint states */
4590 + # define BPS_INVALID 0x0100 /* got "breakpoints-invalid" annotation */
4591 + # define BPS_BP_HIT 0x0200 /* got "breakpoint" annotation */
4592 + # define BPS_FR_INVALID 0x0400 /* got "frames-invalid" annotation */
4593 + # define BPS_BP_SET 0x0800 /* a break type GDB cmd is being processed */
4594 + # define BPS_RECORD 0x1000 /* parsing a record in the breakpoint table */
4595 + # define BPS_START 0x2000 /* start of a record */
4596 + #endif /* defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT) */
4598 + #ifdef GDB_LVL2_SUPPORT
4599 + /* level 2 annotations */
4600 + # define ANO_FRAME_BEGIN 201
4601 + # define ANO_FRAME_END 202
4602 + # define ANO_BP_HEADER 203
4603 + # define ANO_BP_TABLE 204
4604 + # define ANO_BP_RECORD 205
4605 + # define ANO_BP_FIELD0 206 /* Number */
4606 + # define ANO_BP_FIELD1 207 /* Type */
4607 + # define ANO_BP_FIELD2 208 /* Disposition */
4608 + # define ANO_BP_FIELD3 209 /* Enable */
4609 + # define ANO_BP_FIELD4 210 /* Address */
4610 + # define ANO_BP_FIELD5 211 /* What */
4611 + # define ANO_BP_FIELD6 212 /* Frame */
4612 + # define ANO_BP_FIELD7 213 /* Condition */
4613 + # define ANO_BP_FIELD8 214 /* Ignore-count */
4614 + # define ANO_BP_FIELD9 215 /* Commands */
4615 + # define ANO_BP_END 216
4616 + # define ANO_DISP_BEG 217
4617 + # define ANO_DISP_NUMEND 218
4618 + # define ANO_DISP_FMT 219
4619 + # define ANO_DISP_EXP 220
4620 + # define ANO_DISP_EXPEND 221
4621 + # define ANO_DISP_VALUE 222 /* not output by GDB */
4622 + # define ANO_DISP_END 223
4623 + # define ANO_FIELD_BEG 224
4624 + # define ANO_FIELD_NAMEND 225
4625 + # define ANO_FIELD_VALUE 226
4626 + # define ANO_FIELD_END 227
4627 + # define ANO_ARRAY_BEG 228
4628 + # define ANO_ARRAY_ELT 229
4629 + # define ANO_ARRAY_ELTREP 230
4630 + # define ANO_ARRAY_ELTEND 231
4631 + # define ANO_ARRAY_END 232
4634 + # define IS_RECORD(s) ((s) & BPS_RECORD)
4635 + # define RECORD_INDEX(s) ((s) & 0xff)
4636 + # define SET_RECORD_IDX(s, i) (((s) & ~0xff) | (i))
4638 + /* breakpoint annotation fields indexes */
4640 + # define BI_TYPE 1
4641 + # define BI_DISPO 2
4642 + # define BI_ENABLE 3
4643 + # define BI_ADDRESS 4
4644 + # define BI_WHAT 5
4645 + # define BI_FRAME 6
4646 + # define BI_COND 7
4647 + # define BI_COUNT 8
4648 + # define BI_CMMDS 9 /* commands */
4649 + # define BI_FIELDS 10 /* number of bp info annotation fields */
4651 + /* The display object structure */
4652 + typedef struct gdbdisp_struct gdbdisp_T;
4654 + struct gdbdisp_struct
4656 + int num; /* display number */
4657 + int state; /* highlighted or/and changed */
4661 + /* display states */
4662 + # define DSP_INIT 0
4663 + # define DSP_STOPPED 1
4665 + /* The display list structure */
4672 + /* The display entry structure used to store a GDB display output */
4675 + char_u * num; /* display item number */
4676 + char_u * expression;/* display item format and expression */
4677 + char_u * value; /* display item value */
4680 + /* The lvl2 mode structure: lvl2 specific data */
4684 + char_u *info[BI_FIELDS]; /* breakpoint info record contents */
4686 + /* variables (display) window */
4687 + displist_T varlist; /* list of display items */
4688 + doutput_T dentry; /* current GDB display output entry */
4689 + int doing_value; /* when TRUE: currently handling a display value */
4690 + char_u *dispinfostr;/* current line output after "info display" */
4691 + char_u *dispinfo; /* all item numbers result of a "info display" */
4693 + #endif /* GDB_LVL2_SUPPORT */
4695 + #ifdef GDB_LVL3_SUPPORT
4696 + /* The variable object structure */
4697 + typedef struct varobj_struct varobj_T;
4699 + /* varobj states */
4700 + #define VS_INIT 0x01 /* object creation */
4701 + #define VS_ERROR 0x02 /* a command on this object produced an error */
4703 + struct varobj_struct
4706 + char_u *name; /* variable name ("NNN" in "varNNN") */
4707 + int children; /* TRUE when has children */
4708 + char_u *format; /* print format is "/[tdxo]"*/
4709 + char_u *expression; /* variable expression */
4713 + /* GDB/MI var commands */
4714 + # define VCMD_INIT 0
4715 + # define VCMD_CREATE 1
4716 + # define VCMD_DELETE 2
4717 + # define VCMD_CHILDREN 3
4718 + # define VCMD_UPDATE 4
4719 + # define VCMD_PRINT 5
4720 + # define VCMD_EVALUATE 6
4721 + # define VCMD_FORMAT 7
4723 + /* The lvl3 mode structure: lvl3 specific data */
4726 + char_u *result; /* result of a GDB/MI command */
4728 + int get_source_list;
4729 + char_u *source_cur; /* result of -file-list-exec-source-file */
4730 + char_u *source_list;/* result of -file-list-exec-source-files */
4732 + /* variables window */
4733 + varobj_T *varlist; /* list of variable objects */
4734 + varobj_T *varitem; /* current object in varlist */
4735 + int varcmd; /* GDB/MI var cmd being processed */
4736 + int varnext_cmd; /* GDB/MI var next cmd to process */
4738 + #endif /* GDB_LVL3_SUPPORT */
4740 + /* Command types */
4743 + # define CMD_DIR 1
4745 + #define CMD_DETACH 2
4746 + #define CMD_SHELL 3
4747 + #define CMD_STEPI 4 /* instruction stepping cmds */
4748 + #define CMD_EXECF 5 /* invalidating asm buffers cmds */
4749 + #define CMD_BREAK 6
4750 + #define CMD_DISPLAY 7
4751 + #define CMD_CREATEVAR 8
4753 + #define CMD_DOWN 10
4754 + #define CMD_FRAME 11
4755 + #define CMD_DISABLE 12
4756 + #define CMD_DELETE 13
4757 + #define CMD_UP_SILENT 14
4758 + #define CMD_DOWN_SILENT 15
4759 + #define CMD_SLECT_FRAME 16
4760 + #define CMD_SYMF 17
4761 + #define CMD_RESTART 18
4762 + #define CMD_QUIT 19
4764 + #define ASM_MAX_BUFF 64 /* asm buffers pool size */
4765 + #define ASM_BUF_NAME "gdb-asm-" /* asm buffer name prefix */
4766 + #define ASM_OLD (char_u)(~0U) /* asm buffer max age */
4768 + /* The assembly buffer pool */
4772 + int max; /* buffers in use */
4773 + int idx; /* current buffer */
4774 + buf_T * buf[ASM_MAX_BUFF]; /* asm buffers */
4775 + char_u age[ASM_MAX_BUFF]; /* buffer's age */
4776 + int last; /* used for generating unique asm names */
4778 + int buf; /* number of the asm buffer being disassembled */
4779 + FILE *fd; /* stream descriptor of asm file being written to */
4780 + char_u *name; /* file name of the function being disassembled */
4781 + long line_offset; /* offset of start of last line in file */
4783 + linenr_T lnum; /* highlited line number */
4784 + int hilite; /* TRUE when $pc in asm is highlited */
4787 + /* The gdb structure */
4788 + typedef struct gdb_struct gdb_T;
4790 + /* Out of band states */
4791 + #define OS_CMD 0x01 /* a cmd is being processed */
4792 + #define OS_INTR 0x02 /* interrupt sent to gdb */
4793 + #define OS_QUIT 0x04 /* 'quit' annotation received */
4797 + #define OOB_COLLECT 1
4798 + #define OOB_COMPLETE 2
4799 + #define IS_OOBACTIVE(t) (((t)->oob.idx) >= 0)
4801 + /* The out of band process */
4804 + int state; /* oob state */
4805 + int idx; /* current function index */
4806 + int cnt; /* asm output lines count */
4810 + * oobfunc_T function:
4812 + * When an oobfunc_T[] array is processed by gdb_oob_send() and
4813 + * gdb_oob_receive(), each oob function in the array is called with
4814 + * successive state values of:
4816 + * OOB_CMD: called at each 'prompt'; should return the GDB cmd
4817 + * to send to GDB or NULL when no command must be sent;
4818 + * in this case the next oob function in the oobfunc_T[]
4819 + * array is processed next with OOB_CMD
4821 + * OOB_COLLECT: oob may process chunk, a (possibly partial) line from GDB
4822 + * result of GDB command; may be invoked more than once, or not at all
4824 + * OOB_COMPLETE:indicates end of GDB output; oob may do any final processing;
4825 + * if oob returns a non NULL value, the same oob function is
4826 + * called once again with OOB_CMD and the same cycle starts again;
4827 + * if oob returns a NULL value, the next oob function in the
4828 + * oobfunc_T[] array is processed with OOB_CMD
4830 + * Return: NULL, except when state is OOB_CMD or OOB_COMPLETE
4834 + char * (*oob)(gdb_T *, int state, char_u *chunk, struct obstack *);
4838 + #define GDB_STATE(i,s) (((i) != NULL) ? ((((gdb_T *)(i))->state) & (s)):FALSE)
4839 + #define GS_INIT 0 /* initial state */
4840 + #define GS_CLOSING 0x001 /* gdb process closing */
4841 + #define GS_UP 0x002 /* gdb up and running */
4842 + #define GS_STARTED 0x004 /* gdb just started */
4843 + #define GS_ALLOWED 0x008 /* select on pty is allowed */
4844 + #define GS_EVENT 0x010 /* got SIGCHLD or gdb output some data */
4845 + #define GS_SIGCHLD 0x020 /* got SIGCHLD from gdb */
4846 + #define GS_STOPPED 0x040 /* debuggee is stopped */
4847 + #define GS_ANO 0x080 /* parsing an annotation table or list */
4848 + #define GS_QUITTING 0x100 /* quitting clewn */
4850 + /* parser states */
4852 + #define PS_PREPROMPT 1 /* before the prompt, after any output from GDB */
4853 + #define PS_PROMPT 2 /* after prompt, but before user input */
4855 + /* project file sourced states */
4856 + #define PROJ_INIT 0
4857 + #define PROJ_SOURCEIT 1
4858 + #define PROJ_DONE 2
4860 + /* The gdb structure */
4864 + int instance; /* gdb instance number */
4865 + int fd; /* pty file descriptor */
4866 + pid_t pid; /* process id */
4867 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4868 + int height; /* pseudo tty height, non zero when ioctl set */
4869 + int intr_sent; /* hack: an interrupt has been sent by the user */
4871 + int state; /* gdb state */
4872 + char_u *status; /* gdb status */
4873 + int recurse; /* disable GS_ALLOWED when calling safe_vgetc */
4876 + int cmd_type; /* cmd type */
4877 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4878 + cli_cmd_T cli_cmd; /* current CLI cmd (common to lvl2 and lvl3) */
4880 + char_u *firstcmd; /* first cmd in new GDB session */
4881 + int parser; /* parser states */
4882 + int syntax; /* when TRUE, enable syntax highlighting */
4883 + char_u *line; /* last incomplete line */
4884 + char_u *winput_cmd; /* cmd inserted in input-line window */
4885 + char_u *directories;/* gdb search path for source files */
4887 + char_u *prompt; /* the current GDB prompt */
4888 + char * version; /* clewn version */
4889 + char_u * pwd; /* current working directory */
4890 + char_u * args; /* debugge command line arguments */
4892 + char_u *sfile; /* symbol file name */
4894 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4896 + int note; /* annotation type */
4897 + int annoted; /* TRUE when parsing an annotation */
4898 + int newline; /* pending NL, possibly an annotation first char */
4899 + int valid_note; /* last non prompt-for-more annotation type */
4900 + int prev_note; /* previous annotation type */
4901 + char_u *annotation; /* last incomplete annotation */
4905 + asm_T pool; /* asm buffers pool */
4906 + char_u *pc; /* program counter where debuggee is stopped */
4907 + char_u *frame_pc; /* current frame program counter */
4908 + char_u *oob_result; /* result of oob gdb_get_frame */
4909 + char_u *asm_add; /* address whose function must be disassembled */
4910 + char_u *asm_func; /* asm function name */
4913 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4914 + int bp_state; /* breakpoint annotation state (and index) */
4915 + bpinfo_T *tmplist; /* tmp new bp list when reading "info beakpoints" */
4917 + bpinfo_T *record; /* current record */
4918 + int bufIsChanged; /* TRUE when curbuf is changed after edit failed */
4919 + int cont; /* TRUE when pgm is continuing at this bp */
4920 + bpinfo_T *bpinfo; /* breakpoints info table */
4921 + int frame_curlvl; /* current frame level */
4922 + linenr_T frame_lnum;/* current frame line number */
4923 + char_u * frame_fname;/* current frame file name */
4926 + buf_T *buf; /* gdb buffer */
4927 + buf_T *fr_buf; /* frame sign buffer */
4928 + buf_T *var_buf; /* variables window buffer */
4929 + #else /* Clewn implementation */
4930 + linenr_T lastline; /* lastline being disassembled */
4931 + int fr_buf; /* frame sign buffer number */
4932 + linenr_T lnum; /* frame sign line number */
4933 + int var_buf; /* variables buffer number */
4934 + char_u *var_name; /* variables file name */
4935 + char_u *balloon_txt;/* text over which is pointed the mouse */
4936 + char * project_file;/* project file name */
4937 + int project_state; /* project file sourced state */
4939 + oob_T oob; /* out of band data */
4941 + /* |+gdb| modes */
4942 + int mode; /* current |+gdb| mode */
4943 + #ifdef GDB_LVL2_SUPPORT
4944 + lvl2_T lvl2; /* annotations level 2 */
4946 + #ifdef GDB_LVL3_SUPPORT
4947 + lvl3_T lvl3; /* annotations level 3 and GDB/MI */
4950 + /* pointers to mode specific functions */
4951 + oobfunc_T *oobfunc; /* the current oob functions array */
4952 + oobfunc_T *std_oobfunc; /* the standard oob functions array */
4953 + int (*parse_output)(gdb_T *); /* parser function */
4954 + void (*gdb_docmd)(gdb_T *, char_u *);/* GDB command input function */
4955 + void (*var_delete)(gdb_T *); /* delete all variables function */
4956 + void (*clear_gdb_T)(gdb_T *); /* clear mode specific stuff */
4959 + /* Regexp patterns */
4961 + #define PAT_CHG_ANNO 2
4965 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4966 + # define PAT_SOURCE 101
4967 + # define PAT_QUERY 102
4968 + # define PAT_YES 103
4969 + # define PAT_SFILE 104
4970 + # define PAT_BP_CONT 105
4971 + # define PAT_ASM_FUNC 106
4972 + # define PAT_ASM_FUNC_P 107
4973 + # define PAT_FRAME 108
4974 + # define PAT_HEIGHT 109
4977 + #ifdef GDB_LVL2_SUPPORT
4978 + # define PAT_BP_ASM 201
4979 + # define PAT_BP_SOURCE 202
4980 + # define PAT_DISPLAY 203
4981 + # define PAT_DISPINFO 204
4982 + # define PAT_CREATEVAR 205
4985 + # ifdef GDB_LVL3_SUPPORT
4986 + # define PAT_CRVAR_FMT 301
4987 + # define PAT_INFO_FRAME 302
4990 + /* User interface */
4991 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4992 + void gdb_docmd_cli __ARGS((gdb_T *, char_u *));
4993 + void gdb_send_cmd __ARGS((gdb_T *, char_u *));
4996 + /* Vim low level hook */
4997 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
4998 + int gdb_parse_output_cli __ARGS((gdb_T *));
5001 + /* Gdb process mgmt */
5002 + void gdb_close __ARGS((gdb_T *));
5003 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
5004 + int gdb_setup_cli __ARGS((gdb_T *));
5007 + /* Gdb mode initialization */
5008 + #ifdef GDB_LVL2_SUPPORT
5009 + void gdb_lvl2_init __ARGS((gdb_T *));
5011 + #ifdef GDB_LVL3_SUPPORT
5012 + void gdb_lvl3_init __ARGS((gdb_T *));
5015 + /* Sign highliting */
5016 + #define FRAME_SIGN 1
5018 + # define PHANTOM_SIGN 2
5019 + # define BP_SIGN_ID(n) ((n)+2) /* reserved sign ids: 1 frame, 2 phantom */
5020 + void gdb_fr_lite __ARGS((gdb_T *, buf_T *, linenr_T, struct obstack *));
5021 + int gdb_define_sign __ARGS((int, int));
5022 + void gdb_undefine_sign __ARGS((int));
5023 + buf_T * gdb_unlite __ARGS((int));
5025 + # define BP_SIGN_ID(n) ((n)+1) /* reserved sign id: 1 frame */
5026 + void gdb_fr_lite __ARGS((gdb_T *, int, linenr_T, struct obstack *));
5027 + int gdb_define_bpsign __ARGS((bpinfo_T *, struct obstack *));
5028 + void gdb_unlite __ARGS((int));
5030 + int gdb_as_frset __ARGS((gdb_T *, struct obstack *));
5031 + int gdb_fr_set __ARGS((gdb_T *, char_u *, linenr_T *, struct obstack *));
5032 + void gdb_fr_unlite __ARGS((gdb_T *));
5034 + /* Window and buffer mgmt */
5036 + win_T *gdb_btowin __ARGS((buf_T *));
5037 + void gdb_as_setname __ARGS((char_u *));
5038 + void gdb_clear_asmbuf __ARGS((gdb_T *, buf_T *));
5039 + win_T * gdb_edit_file __ARGS((gdb_T *, buf_T *, char_u *, linenr_T, struct obstack *));
5040 + void gdb_set_cursor __ARGS((win_T *, linenr_T));
5041 + void gdb_popup_console __ARGS((gdb_T *));
5042 + void gdb_redraw __ARGS((buf_T *));
5044 + int gdb_edit_file __ARGS((int, char_u *, linenr_T, int, struct obstack *));
5046 + void gdb_msg_busy __ARGS((char_u *));
5047 + void gdb_showBalloon __ARGS((char_u *, struct obstack *));
5048 + void gdb_status __ARGS((gdb_T *, char_u *, struct obstack *));
5049 + void gdb_write_buf __ARGS((gdb_T *, char_u *, int));
5052 + void gdb_oob_send __ARGS((gdb_T *, struct obstack *));
5053 + void gdb_oob_receive __ARGS((gdb_T *, char_u *, struct obstack *));
5054 + #if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
5055 + char * gdb_print_value __ARGS((gdb_T *, int, char_u *, struct obstack *));
5056 + char * gdb_get_pc __ARGS((gdb_T *, int, char_u *, struct obstack *));
5057 + char * gdb_get_frame __ARGS((gdb_T *, int, char_u *, struct obstack *));
5058 + char * gdb_info_frame __ARGS((gdb_T *, int, char_u *, struct obstack *));
5059 + char * gdb_stack_frame __ARGS((gdb_T *, int, char_u *, struct obstack *));
5060 + char * gdb_get_sfile __ARGS((gdb_T *, int, char_u *, struct obstack *));
5062 + char * gdb_source_project __ARGS((gdb_T *, int, char_u *, struct obstack *));
5063 + char * gdb_get_pwd __ARGS((gdb_T *, int, char_u *, struct obstack *));
5064 + char * gdb_get_args __ARGS((gdb_T *, int, char_u *, struct obstack *));
5066 + char * gdb_source_cur __ARGS((gdb_T *, int, char_u *, struct obstack *));
5067 + char * gdb_source_list __ARGS((gdb_T *, int, char_u *, struct obstack *));
5068 + char * gdb_get_sourcedir __ARGS((gdb_T *, int, char_u *, struct obstack *));
5069 + char * gdb_get_asmfunc __ARGS((gdb_T *, int, char_u *, struct obstack *));
5070 + char * gdb_get_asmfunc_hack __ARGS((gdb_T *, int, char_u *, struct obstack *));
5071 + char * gdb_get_asm __ARGS((gdb_T *, int, char_u *, struct obstack *));
5072 + void gdb_process_record __ARGS((gdb_T *, char_u *, char_u *, char_u *, char_u *, struct obstack *));
5075 + /* Variables window management */
5076 + #ifdef GDB_LVL2_SUPPORT
5077 + void gdb_process_display __ARGS((gdb_T *, char_u *, struct obstack *));
5082 + #define MIN(a,b) (((a)<(b))?(a):(b))
5085 + #define ABS(x) (((x)<0)?(-(x)):(x))
5087 + #define STRCHR(s,c) (char_u *)strchr((char *)(s),(int)(c))
5088 + #define STRSTR(h,n) (char_u *)strstr((char *)(h),(char *)(n))
5089 + #define FREE(p) {xfree((p)); (p) = NULL;}
5090 + #define IS_ANNOTATION(l) (STRSTR((l),"\032\032") == (l))
5091 + #define BUFLASTL(b) (!(((b)->b_ml.ml_flags) & ML_EMPTY)?((b)->b_ml.ml_line_count):0)
5092 + int gdb_read __ARGS((gdb_T *, char_u *, int, int));
5093 + void gdb_free_bplist __ARGS((bpinfo_T **));
5094 + void gdb_cmd_type __ARGS((gdb_T *, char_u *));
5095 + void gdb_cat __ARGS((char_u **, char_u *));
5096 + char_u * gdb_regexec __ARGS((char_u *, int, int, struct obstack *));
5097 + char_u * gdb_itoa __ARGS((int));
5099 + /* Gdb memory leaks mtrace */
5100 + #if defined(GDB_MTRACE) && defined(HAVE_MTRACE)
5101 + # include <malloc.h>
5102 + # include <mcheck.h>
5103 + /* storage for mtrace hooks */
5104 + extern __ptr_t (*s_malloc) (size_t, const void *);
5105 + extern void (*s_free) (void *, const void *);
5106 + extern __ptr_t (*s_realloc) (void *, size_t, const void *);
5108 + # define mv_hooks() do { \
5109 + s_malloc = __malloc_hook; \
5110 + s_free = __free_hook; \
5111 + s_realloc = __realloc_hook; \
5112 + __malloc_hook = NULL; \
5113 + __free_hook = NULL; \
5114 + __realloc_hook = NULL; \
5117 + # define get_hooks() do { \
5118 + __malloc_hook = s_malloc; \
5119 + __free_hook = s_free; \
5120 + __realloc_hook = s_realloc; \
5123 + /* we do call sometimes vim_free directly and allocation is not mtraced:
5124 + * when the called Vim function does not free all its allocated memory
5125 + * after it returns */
5126 + # define xmalloc(s) ({char_u *mret; get_hooks(); mret=xmalloc((s)); mv_hooks(); mret;})
5127 + # define xcalloc(s) ({char_u *mret; get_hooks(); mret=xcalloc((s)); mv_hooks(); mret;})
5128 + # define xrealloc(m,s) ({char_u *mret; get_hooks(); mret=xrealloc((m),(s)); mv_hooks(); mret;})
5130 + # define xfree(x) do { \
5136 + # define clewn_strsave(s) ({char_u *mret; get_hooks(); mret=clewn_strsave((s)); mv_hooks(); mret;})
5137 + # define clewn_strnsave(s,l) ({char_u *mret; get_hooks(); mret=clewn_strnsave((s),(l)); mv_hooks(); mret;})
5139 + # define vim_strsave_escaped(s,e) ({char_u *mret; get_hooks(); mret=vim_strsave_escaped((s),(e)); mv_hooks(); mret;})
5140 + # define vim_regcomp(s,m) ({regprog_T *mret; get_hooks(); mret=vim_regcomp((s),(m)); mv_hooks(); mret;})
5141 + # define FullName_save(n,f) ({char_u *mret; get_hooks(); mret=FullName_save((n),(f)); mv_hooks(); mret;})
5142 + # define get_option_value(n,u,s,o) ({int r; get_hooks(); r=get_option_value((n),(u),(s),(o)); mv_hooks(); r;})
5143 + #endif /* GDB_MTRACE */
5144 + #endif /* GDB_H */
5146 diff -c --new-file old/clewn/gdb_lvl2.c src/clewn/gdb_lvl2.c
5147 *** old/clewn/gdb_lvl2.c 1970-01-01 01:00:00.000000000 +0100
5148 --- src/clewn/gdb_lvl2.c 2008-10-13 16:38:07.000000000 +0200
5152 + /* vi:set ts=8 sts=4 sw=4:
5154 + * Copyright (C) 2004 Xavier de Gaye.
5156 + * This program is free software; you can redistribute it and/or modify
5157 + * it under the terms of the GNU General Public License as published by
5158 + * the Free Software Foundation; either version 2, or (at your option)
5159 + * any later version.
5161 + * This program is distributed in the hope that it will be useful,
5162 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
5163 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5164 + * GNU General Public License for more details.
5166 + * You should have received a copy of the GNU General Public License
5167 + * along with this program (see the file COPYING); if not, write to the
5168 + * Free Software Foundation, Inc.,
5169 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
5171 + * $Id: gdb_lvl2.c 222 2008-10-13 14:38:07Z xavier $
5174 + # ifdef HAVE_CLEWN
5175 + # include <config.h>
5176 + # include "obstack.h"
5177 + # include "clewn.h"
5180 + # include "clewn/obstack.h"
5183 + #if defined(FEAT_GDB) || defined(HAVE_CLEWN)
5186 + # include "misc.h"
5188 + # ifdef GDB_LVL2_SUPPORT
5190 + /* display item states */
5191 + # define DISP_CHANGED 0x01 /* item expression value has changed */
5192 + # define DISP_HILITED 0x02 /* item expression value is hilited */
5194 + /* Gdb process mgmt */
5195 + static void clear_gdb_T __ARGS((gdb_T *));
5198 + static char *get_lastbp __ARGS((gdb_T *, int, char_u *, struct obstack *));
5199 + static char *get_bp __ARGS((gdb_T *, int, char_u *, struct obstack *));
5200 + static void process_record __ARGS((gdb_T *, struct obstack *));
5201 + static void set_bpfield __ARGS((gdb_T *, char_u *));
5202 + static char *get_display __ARGS((gdb_T *, int, char_u *, struct obstack *));
5203 + static char *undisplay __ARGS((gdb_T *, int, char_u *, struct obstack *));
5205 + /* Variables window management */
5206 + static void var_delete __ARGS((gdb_T *));
5208 + /* The function ordering in this array is important as some of
5209 + * these functions must be invoked in the right order */
5210 + static oobfunc_T oobfunc[] = {
5214 + {gdb_get_sourcedir},
5215 + {get_lastbp}, /* after gdb_get_frame */
5216 + {gdb_get_asmfunc}, /* after get_lastbp */
5217 + {gdb_get_asmfunc_hack}, /* after gdb_get_asmfunc */
5218 + {gdb_get_asm}, /* after gdb_get_asmfunc */
5219 + {get_bp}, /* after gdb_get_asm and get_lastbp */
5225 + /* Initialize the gdb_T structure lvl2 component that lvl2 is responsible for */
5230 + gdbdisp_T *item, *next;
5235 + for (item = this->lvl2.varlist.list; item != NULL; item = next)
5237 + next = item->next;
5240 + this->lvl2.varlist.list = NULL;
5242 + for (i = 0; i < BI_FIELDS; i++)
5243 + FREE(this->lvl2.info[i]);
5245 + this->lvl2.doing_value = FALSE;
5246 + FREE(this->lvl2.dentry.num);
5247 + FREE(this->lvl2.dentry.expression);
5248 + FREE(this->lvl2.dentry.value);
5249 + FREE(this->lvl2.dispinfostr);
5250 + FREE(this->lvl2.dispinfo);
5254 + /* Initialize lvl2 function pointers */
5256 + gdb_lvl2_init(this)
5259 + this->mode = GDB_MODE_LVL2;
5260 + this->oobfunc = oobfunc;
5261 + this->std_oobfunc = oobfunc;
5262 + this->parse_output = gdb_parse_output_cli;
5263 + this->gdb_docmd = gdb_docmd_cli;
5264 + this->var_delete = var_delete;
5265 + this->clear_gdb_T = clear_gdb_T;
5269 + * When a breakpoint is being set and asm option is on, get the
5270 + * instruction address of the last breakpoint, the one being set.
5271 + * This address is used in get_asm() to disassemble the function
5272 + * containing this address.
5275 + get_lastbp(this, state, line, obs)
5279 + struct obstack *obs;
5281 + int found = FALSE;
5286 + if (obs) {} /* keep compiler happy */
5291 + /* GDB sends sometimes ANO_BP_INVALID when stepping, even
5292 + * though no breakpoints have been changed.
5293 + * Avoid checking for last bp in this case, because this
5294 + * may cause hiliting a bp in a new buffer when what is
5295 + * expected is a new frame */
5296 + if (this->bp_state & BPS_FR_INVALID)
5299 + /* A breakpoint is being set in assembly */
5300 + if (p_asm != 0 && (this->bp_state & BPS_INVALID)
5301 + && (this->bp_state & BPS_BP_SET))
5303 + this->bp_state &= ~BPS_BP_SET;
5305 + /* fetch GDB bp table info */
5306 + return "server info breakpoint\n";
5311 + /* initialize fields at start of bp record */
5312 + if (this->bp_state & BPS_START)
5314 + this->bp_state &= ~BPS_START;
5316 + for (i = 0; i < BI_FIELDS; i++)
5317 + FREE(this->lvl2.info[i]);
5320 + /* get info[] field from annotation content */
5321 + set_bpfield(this, line);
5324 + case OOB_COMPLETE:
5325 + /* the last bp in the table */
5326 + if (this->lvl2.info[BI_NUM] != NULL
5327 + && (bp_num = atoi((char *)this->lvl2.info[BI_NUM])) > 0)
5329 + /* look it up in bpinfo list */
5330 + for (p = this->bpinfo; p != NULL; p = p->next)
5332 + if (bp_num == p->id)
5339 + /* not found: set asm_add so that get_asm will
5340 + * do the disassembling */
5343 + xfree(this->asm_add);
5345 + gdb_regexec(this->lvl2.info[BI_ADDRESS], PAT_ADD, 1, NULL);
5349 + for (i = 0; i < BI_FIELDS; i++)
5350 + FREE(this->lvl2.info[i]);
5357 + * Get the breakpoints info record table.
5360 + get_bp(this, state, line, obs)
5364 + struct obstack *obs;
5372 + /* When an ANO_BP_INVALID annotation has been received,
5373 + * or when we are stepping (more accurately: got a new frame):
5374 + * fetch bp table */
5375 + if (this->bp_state & BPS_INVALID || this->bp_state & BPS_FR_INVALID)
5377 + this->bufIsChanged = FALSE;
5379 + /* handle case where an error occured last time */
5380 + FREE(this->record);
5381 + gdb_free_bplist(&(this->tmplist));
5383 + return "server info breakpoint\n";
5386 + this->bp_state &= ~BPS_INVALID;
5387 + this->bp_state &= ~BPS_FR_INVALID;
5388 + this->bp_state &= ~BPS_BP_HIT;
5392 + if (this->bp_state & BPS_START)
5394 + this->bp_state &= ~BPS_START;
5396 + /* process last record */
5397 + process_record(this, obs);
5398 + for (i = 0; i < BI_FIELDS; i++)
5399 + FREE(this->lvl2.info[i]);
5401 + /* allocate a new record or reuse an existing one
5402 + * and initialize its fields */
5403 + if (this->record == NULL)
5404 + this->record = (bpinfo_T *)xcalloc(sizeof(bpinfo_T));
5406 + this->record->id = -1;
5407 + this->record->enabled = TRUE;
5408 + # ifdef BP_INVALID_ANO_MISSING
5409 + this->record->disposition = TRUE;
5411 + this->record->cont = FALSE;
5413 + this->record->buf = NULL;
5415 + this->record->buf = -1;
5416 + this->record->typenr_en = -1;
5417 + this->record->typenr_dis = -1;
5419 + this->record->lnum = 0;
5420 + this->record->next = NULL;
5423 + /* get info[] field from annotation content */
5424 + set_bpfield(this, line);
5427 + case OOB_COMPLETE:
5428 + /* process last record */
5429 + process_record(this, obs);
5430 + FREE(this->record);
5431 + for (i = 0; i < BI_FIELDS; i++)
5432 + FREE(this->lvl2.info[i]);
5434 + /* All records left in the old table are breakpoints that have
5435 + * been deleted: delete the corresponding highliting sign */
5436 + for (p = this->bpinfo; p != NULL; p = p->next)
5437 + gdb_unlite(BP_SIGN_ID(p->id));
5439 + this->bp_state &= ~BPS_INVALID;
5440 + this->bp_state &= ~BPS_FR_INVALID;
5441 + this->bp_state &= ~BPS_BP_HIT;
5443 + /* replace with new table */
5444 + gdb_free_bplist(&(this->bpinfo));
5445 + this->bpinfo = this->tmplist;
5446 + this->tmplist = NULL;
5452 + /* Process the current info record */
5454 + process_record(this, obs)
5456 + struct obstack *obs;
5458 + bpinfo_T *record = this->record;
5459 + char_u *bp_add = NULL;
5460 + char_u *bp_at = NULL;
5461 + char_u *bp_line = NULL;
5462 + char_u *bp_source = NULL;
5465 + if (record == NULL)
5468 + /* breakpoint number */
5469 + if (this->lvl2.info[BI_NUM] != NULL)
5470 + record->id = atoi((char *)this->lvl2.info[BI_NUM]);
5472 + /* enabled state */
5473 + if (this->lvl2.info[BI_ENABLE] != NULL && *(this->lvl2.info[BI_ENABLE]) == 'n')
5474 + record->enabled = FALSE;
5476 + # ifdef BP_INVALID_ANO_MISSING
5478 + if (this->lvl2.info[BI_DISPO] != NULL
5479 + && STRSTR(this->lvl2.info[BI_DISPO], "keep") == NULL)
5480 + record->disposition = FALSE;
5483 + /* parse 'commands' for 'continue' as last statement */
5484 + if (this->lvl2.info[BI_CMMDS] != NULL)
5486 + /* get last line */
5487 + if ((ptr = (char_u *)strrchr(
5488 + (char *)this->lvl2.info[BI_CMMDS], (int)'\n')) == NULL)
5489 + ptr = this->lvl2.info[BI_CMMDS];
5493 + if (gdb_regexec(ptr, PAT_BP_CONT, 1, obs) != NULL
5494 + || gdb_regexec(ptr, PAT_BP_CONT, 2, obs) != NULL)
5496 + record->cont = TRUE; /* continue */
5500 + /* sanity check and discard watchpoints and others */
5501 + if (record->id <= 0 || this->lvl2.info[BI_TYPE] == NULL
5502 + || STRSTR(this->lvl2.info[BI_TYPE], "breakpoint") == NULL
5503 + || this->lvl2.info[BI_ADDRESS] == NULL
5504 + || this->lvl2.info[BI_WHAT] == NULL)
5507 + bp_add = gdb_regexec(this->lvl2.info[BI_ADDRESS], PAT_ADD, 1, obs);
5508 + bp_line = gdb_regexec(this->lvl2.info[BI_WHAT], PAT_BP_SOURCE, 2, obs);
5509 + bp_source = gdb_regexec(this->lvl2.info[BI_WHAT], PAT_BP_SOURCE, 1, obs);
5510 + if ((bp_at = gdb_regexec(this->lvl2.info[BI_WHAT], PAT_BP_ASM, 1, obs)) == NULL)
5511 + bp_at = gdb_regexec(this->lvl2.info[BI_WHAT], PAT_BP_ASM, 2, obs);
5513 + gdb_process_record(this, bp_add, bp_at, bp_line, bp_source, obs);
5516 + /* Set the annotated indexed field with its possibly partial content */
5518 + set_bpfield(this, content)
5522 + char_u *res = NULL;
5526 + * Set info[] with each breakpoint info field annotation
5528 + if (IS_RECORD(this->bp_state))
5530 + pfield = &(this->lvl2.info[RECORD_INDEX(this->bp_state)]);
5532 + if (*pfield == NULL) /* a new field */
5533 + *pfield = (char_u *)clewn_strsave((char *)content);
5534 + else if (this->annoted) /* concatenate */
5536 + gdb_cat(&res, *pfield);
5537 + gdb_cat(&res, content);
5541 + else /* a new line in this field */
5543 + gdb_cat(&res, *pfield);
5544 + gdb_cat(&res, (char_u *)"\n");
5545 + gdb_cat(&res, content);
5553 + * Remove highlighting for all values that are unchanged and get
5554 + * from GDB the current "automatic display list"
5557 + get_display(this, state, line, obs)
5561 + struct obstack *obs;
5563 + char_u *res = NULL;
5568 + buf_T *oldbuf = curbuf;
5578 + /* tell Vim to not update screen */
5579 + cnb_startAtomic(this->var_buf);
5584 + this->var_buf != NULL && this->lvl2.varlist.state == DSP_STOPPED)
5586 + this->var_buf > 0 && this->lvl2.varlist.state == DSP_STOPPED)
5589 + /* remove highlighting for all values that are unchanged */
5590 + for (item = this->lvl2.varlist.list; item != NULL; item = item->next)
5593 + if (! (this->var_buf->b_ml.ml_flags & ML_EMPTY)
5594 + && ! (item->state & DISP_CHANGED)
5595 + && (item->state & DISP_HILITED))
5600 + /* search for display item in variables window */
5601 + obstack_strcat(obs, "^\\s*");
5602 + obstack_strcat(obs, gdb_itoa(item->num));
5603 + obstack_strcat0(obs, ":");
5604 + ptrn = (char_u *)obstack_finish(obs);
5606 + if (searchit(NULL, this->var_buf, &pos,
5607 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
5609 + oldline = ml_get_buf(this->var_buf, pos.lnum, FALSE);
5610 + oldline = obstack_strsave(obs, oldline);
5612 + /* this assumes that "={*}" is not valid in
5613 + * any expression or value for all GDB supported
5615 + if ((ptr = STRSTR(oldline, " ={*} ")) != NULL)
5619 + /* replace line */
5620 + curbuf = this->var_buf;
5621 + ml_replace(pos.lnum, oldline, TRUE);
5622 + changed_lines(pos.lnum, 0, pos.lnum + 1, 0);
5625 + if ((win = gdb_btowin(this->var_buf)) != NULL)
5626 + redraw_win_later(win, NOT_VALID);
5630 + item->state &= ~DISP_HILITED;
5633 + if (! (item->state & DISP_CHANGED)
5634 + && (item->state & DISP_HILITED))
5638 + /* search for display item in variables window */
5639 + if ((oldline = cnb_search_obj(gdb_itoa(item->num), &lnum)) != NULL)
5641 + line = obstack_strsave(obs, oldline);
5643 + /* this assumes that "={*}" is not valid in
5644 + * any expression or value for all GDB supported
5646 + if ((ptr = STRSTR(line, " ={*} ")) != NULL)
5650 + /* replace line */
5651 + cnb_replace(this->var_buf, line, lnum, obs);
5654 + item->state &= ~DISP_HILITED;
5658 + item->state &= ~DISP_CHANGED;
5661 + FREE(this->lvl2.dispinfostr);
5662 + xfree(this->lvl2.dispinfo);
5663 + this->lvl2.dispinfo = (char_u *)clewn_strsave(" ");
5664 + return "server info display\n";
5669 + if (this->annoted) /* concatenate */
5671 + gdb_cat(&res, this->lvl2.dispinfostr);
5672 + gdb_cat(&res, line);
5673 + xfree(this->lvl2.dispinfostr);
5674 + this->lvl2.dispinfostr = res;
5676 + else /* a new line */
5678 + /* add item number to list */
5679 + if ((res = gdb_regexec(this->lvl2.dispinfostr, PAT_DISPINFO, 1, obs)) != NULL)
5681 + gdb_cat(&(this->lvl2.dispinfo), res);
5682 + gdb_cat(&(this->lvl2.dispinfo), (char_u *)" ");
5685 + xfree(this->lvl2.dispinfostr);
5686 + this->lvl2.dispinfostr = (char_u *)clewn_strsave((char *)line);
5690 + case OOB_COMPLETE:
5691 + /* add last item number to list */
5692 + if ((res = gdb_regexec(this->lvl2.dispinfostr, PAT_DISPINFO, 1, obs)) != NULL)
5694 + gdb_cat(&(this->lvl2.dispinfo), res);
5695 + gdb_cat(&(this->lvl2.dispinfo), (char_u *)" ");
5697 + FREE(this->lvl2.dispinfostr);
5704 + * Synchronise the gdb variables window list and our varlist with
5705 + * GDB "automatic display list".
5706 + * It should be sufficient that all items in varlist are included
5707 + * both in the gdb variables window list and in GDB
5708 + * "automatic display list".
5711 + undisplay(this, state, line, obs)
5715 + struct obstack *obs;
5718 + char_u *sequence = NULL; /* sequence of items to undisplay */
5719 + win_T *oldwin = curwin;
5720 + buf_T *oldbuf = curbuf;
5732 + if (this->lvl2.varlist.state == DSP_STOPPED)
5734 + for (pt = &(this->lvl2.varlist.list); *pt != NULL; )
5736 + numstr = gdb_itoa((*pt)->num);
5738 + /* not in * GDB "automatic display list" */
5739 + obstack_strcat(obs, " ");
5740 + obstack_strcat(obs, numstr);
5741 + obstack_strcat0(obs, " ");
5742 + num = (char_u *)obstack_finish(obs);
5744 + if (this->lvl2.dispinfo != NULL
5745 + && this->var_buf != NULL
5746 + && STRSTR(this->lvl2.dispinfo, num) == NULL)
5751 + /* remove line from window if exists */
5752 + obstack_strcat(obs, "^\\s*");
5753 + obstack_strcat(obs, numstr);
5754 + obstack_strcat0(obs, ":");
5755 + ptrn = (char_u *)obstack_finish(obs);
5757 + if (! (this->var_buf->b_ml.ml_flags & ML_EMPTY)
5758 + && searchit(NULL, this->var_buf, &pos,
5759 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
5761 + curbuf = this->var_buf;
5762 + ml_delete(pos.lnum, FALSE);
5763 + deleted_lines(pos.lnum, 1);
5765 + if ((win = gdb_btowin(this->var_buf)) != NULL)
5772 + win->w_redr_status = TRUE;
5774 + redraw_win_later(win, NOT_VALID);
5779 + /* remove from varlist */
5780 + next = (*pt)->next;
5787 + /* not in gdb variables window */
5788 + obstack_strcat(obs, "^\\s*");
5789 + obstack_strcat(obs, numstr);
5790 + obstack_strcat0(obs, ":");
5791 + ptrn = (char_u *)obstack_finish(obs);
5793 + if (this->var_buf == NULL
5794 + || (this->var_buf->b_ml.ml_flags & ML_EMPTY)
5795 + || (searchit(NULL, this->var_buf, &pos,
5796 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) == FAIL))
5798 + /* add to sequence */
5799 + obstack_strcat(obs, numstr);
5800 + obstack_strcat0(obs, " ");
5801 + sequence = (char_u *)obstack_finish(obs);
5803 + /* remove from varlist */
5804 + next = (*pt)->next;
5811 + pt = &((*pt)->next);
5814 + this->lvl2.varlist.state = DSP_INIT;
5815 + FREE(this->lvl2.dispinfo);
5817 + if (sequence != NULL)
5819 + obstack_strcat(obs, "server undisplay ");
5820 + obstack_strcat(obs, sequence);
5821 + obstack_strcat0(obs, "\n");
5822 + return (char *)obstack_finish(obs);
5827 + case OOB_COMPLETE:
5828 + line = NULL; /* keep compiler happy */
5835 + char_u *sequence = NULL; /* sequence of items to undisplay */
5845 + if (this->lvl2.varlist.state == DSP_STOPPED)
5847 + for (pt = &(this->lvl2.varlist.list); *pt != NULL; )
5849 + numstr = gdb_itoa((*pt)->num);
5851 + /* not in * GDB "automatic display list" */
5852 + obstack_strcat(obs, " ");
5853 + obstack_strcat(obs, numstr);
5854 + obstack_strcat0(obs, " ");
5855 + num = (char_u *)obstack_finish(obs);
5857 + if (this->lvl2.dispinfo != NULL
5858 + && this->var_buf > 0
5859 + && STRSTR(this->lvl2.dispinfo, num) == NULL)
5861 + /* replace line in window if exists with an empty line */
5862 + if (cnb_search_obj(numstr, &lnum) != NULL)
5863 + cnb_replace(this->var_buf, "", lnum, obs);
5865 + /* remove from varlist */
5866 + next = (*pt)->next;
5873 + /* not in gdb variables window */
5874 + if (this->var_buf <= 0 || cnb_search_obj(numstr, &lnum) == NULL)
5876 + /* add to sequence */
5877 + obstack_strcat(obs, numstr);
5878 + obstack_strcat0(obs, " ");
5879 + sequence = (char_u *)obstack_finish(obs);
5881 + /* remove from varlist */
5882 + next = (*pt)->next;
5889 + pt = &((*pt)->next);
5892 + this->lvl2.varlist.state = DSP_INIT;
5893 + FREE(this->lvl2.dispinfo);
5895 + if (sequence != NULL)
5897 + obstack_strcat(obs, "server undisplay ");
5898 + obstack_strcat(obs, sequence);
5899 + obstack_strcat0(obs, "\n");
5900 + return (char_u *)obstack_finish(obs);
5903 + /* tell Vim to update screen */
5904 + cnb_endAtomic(this->var_buf);
5907 + case OOB_COMPLETE:
5908 + /* tell Vim to update screen */
5909 + cnb_endAtomic(this->var_buf);
5910 + line = NULL; /* keep compiler happy */
5918 + * Handle the content of a display annotation.
5919 + * Fill up each field.
5920 + * When entry complete, process it:
5921 + * . if it's the result of a GDB "display" command with an argument:
5922 + * add to variables window and varlist
5923 + * . if it is the output produced by GDB when the program stops or
5924 + * an equivalent GDB "display" command without argument: hilite
5925 + * changed values in variables window
5928 + gdb_process_display(this, line, obs)
5930 + char_u *line; /* display annotation content */
5931 + struct obstack *obs;
5933 + char_u *res = NULL;
5934 + int note = this->note;
5935 + char_u *displine; /* the new display item line */
5937 + char_u *last, *end, *start;
5941 + win_T *oldwin = curwin;
5942 + buf_T *oldbuf = curbuf;
5950 + if (this->var_buf == NULL)
5952 + if (this->var_buf <= 0)
5956 + /* GDB bug: outputs ANO_DISP_EXP instead of ANO_DISP_VALUE
5957 + * use doing_value as a hack to know when we are parsing the value */
5958 + if (this->lvl2.doing_value && note == ANO_DISP_EXP)
5959 + note = ANO_DISP_VALUE;
5961 + /* nested structure or array */
5962 + if (this->lvl2.doing_value
5963 + && ((note >= ANO_FIELD_BEG && note <= ANO_FIELD_END)
5964 + || (note >= ANO_ARRAY_BEG && note <= ANO_ARRAY_END)))
5965 + note = ANO_DISP_VALUE;
5969 + case ANO_DISP_BEG:
5971 + /* tell Vim to not update screen */
5972 + cnb_startAtomic(this->var_buf);
5975 + this->lvl2.doing_value = FALSE;
5977 + /* display number */
5978 + if (this->lvl2.dentry.num == NULL)
5979 + this->lvl2.dentry.num = (char_u *)clewn_strsave((char *)line);
5982 + gdb_cat(&res, this->lvl2.dentry.num);
5983 + gdb_cat(&res, line);
5984 + xfree(this->lvl2.dentry.num);
5985 + this->lvl2.dentry.num = res;
5989 + case ANO_DISP_FMT:
5990 + case ANO_DISP_EXP:
5991 + /* display format and expression */
5992 + if (this->lvl2.dentry.expression == NULL)
5993 + this->lvl2.dentry.expression = (char_u *)clewn_strsave((char *)line);
5996 + gdb_cat(&res, this->lvl2.dentry.expression);
5997 + gdb_cat(&res, line);
5998 + xfree(this->lvl2.dentry.expression);
5999 + this->lvl2.dentry.expression = res;
6003 + case ANO_DISP_EXPEND:
6004 + this->lvl2.doing_value = TRUE;
6007 + case ANO_DISP_VALUE:
6008 + /* display value */
6009 + if (this->lvl2.dentry.value == NULL)
6010 + this->lvl2.dentry.value = (char_u *)clewn_strsave((char *)line);
6013 + gdb_cat(&res, this->lvl2.dentry.value);
6014 + gdb_cat(&res, line);
6015 + xfree(this->lvl2.dentry.value);
6016 + this->lvl2.dentry.value = res;
6020 + /* Process the entry now it's complete */
6021 + case ANO_DISP_END:
6022 + this->lvl2.doing_value = FALSE;
6024 + /* sanity checks */
6025 + if (this->lvl2.dentry.num == NULL
6026 + || (num = atoi((char *)this->lvl2.dentry.num)) <= 0
6027 + || this->lvl2.dentry.expression == NULL
6028 + || this->lvl2.dentry.value == NULL)
6030 + FREE(this->lvl2.dentry.num);
6031 + FREE(this->lvl2.dentry.expression);
6032 + FREE(this->lvl2.dentry.value);
6036 + /* Build the display line including ={*}, the hiliting sign */
6037 + obstack_strcat(obs, this->lvl2.dentry.num);
6038 + obstack_strcat(obs, ":");
6039 + obstack_strcat(obs, this->lvl2.dentry.expression);
6040 + obstack_strcat(obs, " ={*} ");
6041 + obstack_strcat0(obs, this->lvl2.dentry.value);
6042 + displine = (char_u *)obstack_finish(obs);
6045 + * The result of a GDB "display" command with argument
6047 + if (this->cmd_type == CMD_DISPLAY)
6049 + item = (gdbdisp_T *)xcalloc(sizeof(gdbdisp_T));
6051 + /* add item to varlist */
6053 + item->state = DISP_HILITED;
6054 + item->next = this->lvl2.varlist.list;
6055 + this->lvl2.varlist.list = item;
6058 + lnum = BUFLASTL(this->var_buf);
6060 + /* edit variables buffer in available window */
6061 + if (gdb_edit_file(this, this->var_buf, NULL, lnum, obs) != NULL)
6063 + /* add to variables buffer */
6064 + if (ml_append(lnum, displine, 0, 0) == OK)
6066 + /* first line ever: remove empty line after the
6067 + * one just inserted */
6069 + ml_delete(this->var_buf->b_ml.ml_line_count, FALSE);
6071 + changed_lines(this->var_buf->b_ml.ml_line_count - 1,
6072 + 0, this->var_buf->b_ml.ml_line_count, 1);
6075 + /* update top line */
6076 + curwin->w_cursor.lnum = this->var_buf->b_ml.ml_line_count;
6079 + /* status line changed */
6080 + curwin->w_redr_status = TRUE;
6082 + /* move back to previous window if still there */
6083 + if ((win = gdb_btowin(oldbuf)) != NULL)
6087 + /* add to variables buffer */
6088 + cnb_append(this->var_buf, displine, obs);
6093 + * Highlight existing changed values in variables window
6101 + /* search for display item in variables window */
6102 + obstack_strcat(obs, "^\\s*");
6103 + obstack_strcat(obs, this->lvl2.dentry.num);
6104 + obstack_strcat0(obs, ":");
6105 + ptrn = (char_u *)obstack_finish(obs);
6107 + if ( ! (this->var_buf->b_ml.ml_flags & ML_EMPTY)
6108 + && searchit(NULL, this->var_buf, &pos,
6109 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
6113 + obstack_strcat(obs, "} ");
6114 + obstack_strcat0(obs, this->lvl2.dentry.value);
6115 + res = (char_u *)obstack_finish(obs);
6118 + start = ml_get_buf(this->var_buf, lnum, FALSE);
6119 + end = start + STRLEN(start);
6121 + /* get last occurence of "} " + value in this line */
6122 + for (ptr = start; ptr != NULL; )
6123 + if ((ptr=STRSTR(ptr, res)) != NULL)
6129 + /* a changed value (res not found at line end) */
6130 + if (last == NULL || end != last + STRLEN(res))
6132 + /* replace line */
6133 + curbuf = this->var_buf;
6134 + ml_replace(lnum, displine, TRUE);
6135 + changed_lines(lnum, 0, lnum + 1, 0);
6137 + if ((win = gdb_btowin(this->var_buf)) != NULL)
6139 + win->w_cursor.lnum = lnum;
6146 + win->w_redr_status = TRUE;
6148 + redraw_win_later(win, NOT_VALID);
6152 + /* update item state */
6153 + for (item = this->lvl2.varlist.list; item != NULL;
6154 + item = item->next)
6155 + if (item->num == num)
6157 + item->state |= DISP_HILITED | DISP_CHANGED;
6165 + /* search for display item in variables window */
6166 + if ((start = cnb_search_obj(this->lvl2.dentry.num, &line_nb)) != NULL)
6168 + obstack_strcat(obs, "} ");
6169 + obstack_strcat0(obs, this->lvl2.dentry.value);
6170 + res = (char_u *)obstack_finish(obs);
6173 + end = start + STRLEN(start);
6175 + /* get last occurence of "} " + value in this line */
6176 + for (ptr = start; ptr != NULL; )
6177 + if ((ptr=STRSTR(ptr, res)) != NULL)
6183 + /* a changed value (res not found at line end) */
6184 + if (last == NULL || end != last + STRLEN(res))
6186 + /* replace line */
6187 + cnb_replace(this->var_buf, displine, line_nb, obs);
6189 + /* update item state */
6190 + for (item = this->lvl2.varlist.list; item != NULL;
6191 + item = item->next)
6192 + if (item->num == num)
6194 + item->state |= DISP_HILITED | DISP_CHANGED;
6202 + FREE(this->lvl2.dentry.num);
6203 + FREE(this->lvl2.dentry.expression);
6204 + FREE(this->lvl2.dentry.value);
6207 + /* tell Vim to update screen */
6208 + cnb_endAtomic(this->var_buf);
6217 + /* Undisplay all variables */
6222 + struct obstack obs; /* use an obstack for temporary allocated memory */
6225 + /* undisplay all */
6226 + this->lvl2.varlist.state = DSP_STOPPED;
6228 + (void)obstack_init(&obs);
6230 + if ((res = (char_u *)undisplay(this, OOB_CMD, (char_u *)"", &obs)) != NULL)
6231 + gdb_send_cmd(this, res);
6233 + obstack_free(&obs, NULL);
6235 + # endif /* GDB_LVL2_SUPPORT */
6236 + #endif /* defined(FEAT_GDB) || defined(HAVE_CLEWN) */
6237 diff -c --new-file old/clewn/gdb_lvl3.c src/clewn/gdb_lvl3.c
6238 *** old/clewn/gdb_lvl3.c 1970-01-01 01:00:00.000000000 +0100
6239 --- src/clewn/gdb_lvl3.c 2008-10-13 16:38:07.000000000 +0200
6243 + /* vi:set ts=8 sts=4 sw=4:
6245 + * Copyright (C) 2004 Xavier de Gaye.
6247 + * This program is free software; you can redistribute it and/or modify
6248 + * it under the terms of the GNU General Public License as published by
6249 + * the Free Software Foundation; either version 2, or (at your option)
6250 + * any later version.
6252 + * This program is distributed in the hope that it will be useful,
6253 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
6254 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6255 + * GNU General Public License for more details.
6257 + * You should have received a copy of the GNU General Public License
6258 + * along with this program (see the file COPYING); if not, write to the
6259 + * Free Software Foundation, Inc.,
6260 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
6262 + * $Id: gdb_lvl3.c 222 2008-10-13 14:38:07Z xavier $
6265 + # ifdef HAVE_CLEWN
6266 + # include <config.h>
6267 + # include "obstack.h"
6268 + # include "clewn.h"
6269 + static int got_int; /* not used with Clewn */
6272 + # include "clewn/obstack.h"
6275 + #if defined(FEAT_GDB) || defined(HAVE_CLEWN)
6278 + # include "misc.h"
6280 + # if defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT)
6282 + static char gdb_buf[MAX_BUFFSIZE]; /* general purpose buffer */
6286 + int id; /* annoted identifier */
6287 + char_u *str; /* GDB annotation */
6290 + static annotation_T annotations[] = {
6291 + {ANO_PREPROMPT, (char_u *)"pre-prompt"},
6292 + {ANO_PROMPT, (char_u *)"prompt"},
6293 + {ANO_POSTPROMPT, (char_u *)"post-prompt"},
6294 + {ANO_PRECMDS, (char_u *)"pre-commands"},
6295 + {ANO_CMDS, (char_u *)"commands"},
6296 + {ANO_PREOVERLOAD, (char_u *)"pre-overload-choice"},
6297 + {ANO_OVERLOAD, (char_u *)"overload-choice"},
6298 + {ANO_PREQUERY, (char_u *)"pre-query"},
6299 + {ANO_QUERY, (char_u *)"query"},
6300 + {ANO_PREPMT_FORMORE, (char_u *)"pre-prompt-for-continue"},
6301 + {ANO_PMT_FORMORE, (char_u *)"prompt-for-continue"},
6302 + {ANO_POSTPMT_FORMORE, (char_u *)"post-prompt-for-continue"},
6303 + {ANO_QUIT, (char_u *)"quit"},
6304 + {ANO_ERROR_BEG, (char_u *)"error-begin"},
6305 + {ANO_FRAME_INVALID, (char_u *)"frames-invalid"},
6306 + {ANO_BP_INVALID, (char_u *)"breakpoints-invalid"},
6307 + {ANO_STARTING, (char_u *)"starting"},
6308 + {ANO_STOPPED, (char_u *)"stopped"},
6309 + {ANO_EXITED, (char_u *)"exited"},
6310 + {ANO_SIGNALLED, (char_u *)"signalled"},
6311 + {ANO_BREAKPOINT, (char_u *)"breakpoint"},
6312 + # ifdef GDB_LVL2_SUPPORT
6313 + {ANO_SOURCE, (char_u *)"source"},
6314 + {ANO_FRAME_BEGIN, (char_u *)"frame-begin"},
6315 + {ANO_FRAME_END, (char_u *)"frame-end"},
6316 + {ANO_BP_HEADER, (char_u *)"breakpoints-headers"},
6317 + {ANO_BP_TABLE, (char_u *)"breakpoints-table"},
6318 + {ANO_BP_RECORD, (char_u *)"record"},
6319 + {ANO_BP_FIELD0, (char_u *)"field 0"},
6320 + {ANO_BP_FIELD1, (char_u *)"field 1"},
6321 + {ANO_BP_FIELD2, (char_u *)"field 2"},
6322 + {ANO_BP_FIELD3, (char_u *)"field 3"},
6323 + {ANO_BP_FIELD4, (char_u *)"field 4"},
6324 + {ANO_BP_FIELD5, (char_u *)"field 5"},
6325 + {ANO_BP_FIELD6, (char_u *)"field 6"},
6326 + {ANO_BP_FIELD7, (char_u *)"field 7"},
6327 + {ANO_BP_FIELD8, (char_u *)"field 8"},
6328 + {ANO_BP_FIELD9, (char_u *)"field 9"},
6329 + {ANO_BP_END, (char_u *)"breakpoints-table-end"},
6330 + {ANO_DISP_BEG, (char_u *)"display-begin"},
6331 + {ANO_DISP_NUMEND, (char_u *)"display-number-end"},
6332 + {ANO_DISP_FMT, (char_u *)"display-format"},
6333 + {ANO_DISP_EXP, (char_u *)"display-expression"},
6334 + {ANO_DISP_EXPEND, (char_u *)"display-expression-end"},
6335 + {ANO_DISP_VALUE, (char_u *)"display-value"},
6336 + {ANO_DISP_END, (char_u *)"display-end"},
6337 + {ANO_FIELD_BEG, (char_u *)"field-begin"},
6338 + {ANO_FIELD_NAMEND, (char_u *)"field-name-end"},
6339 + {ANO_FIELD_VALUE, (char_u *)"field-value"},
6340 + {ANO_FIELD_END, (char_u *)"field-end"},
6341 + {ANO_ARRAY_BEG, (char_u *)"array-section-begin"},
6342 + {ANO_ARRAY_ELT, (char_u *)"elt"},
6343 + {ANO_ARRAY_ELTREP, (char_u *)"elt-rep"},
6344 + {ANO_ARRAY_ELTEND, (char_u *)"elt-rep-end"},
6345 + {ANO_ARRAY_END, (char_u *)"array-section-end"},
6350 + /* User interface */
6351 + static char_u *process_cmd __ARGS((gdb_T *, char_u *));
6353 + /* Vim low level hook */
6354 + /* Not allowed after ^O in INS REP mode or from the input-line window */
6355 + static char_u *process_annotation __ARGS((gdb_T *, char_u *, struct obstack *));
6356 + static char_u * process_completion __ARGS((cli_cmd_T *, char_u *, struct obstack *));
6357 + static char_u * eol_choices __ARGS((cli_cmd_T *, struct obstack *));
6359 + # ifdef GDB_LVL3_SUPPORT
6360 + /* Gdb process mgmt */
6361 + static void clear_gdb_T __ARGS((gdb_T *));
6364 + static char *get_lastbp __ARGS((gdb_T *, int, char_u *, struct obstack *));
6365 + static char *get_bp __ARGS((gdb_T *, int, char_u *, struct obstack *));
6366 + static void process_record __ARGS((gdb_T *, char_u *, struct obstack *));
6367 + static char *varobj_update __ARGS((gdb_T *, int, char_u *, struct obstack *));
6368 + static char *varobj_complete __ARGS((gdb_T *, struct obstack *));
6369 + static void varobj_hilite __ARGS((gdb_T *, varobj_T *, int, struct obstack *));
6370 + static void varobj_replace __ARGS((gdb_T *, varobj_T *, char_u *, struct obstack *));
6371 + static void remove_object __ARGS((gdb_T *, varobj_T *));
6375 + static char_u * parse_note __ARGS((gdb_T *, char_u *));
6377 + static int get_note __ARGS((gdb_T *, char_u *));
6380 + # ifdef GDB_LVL3_SUPPORT
6381 + /* The function ordering in this array is important as some of
6382 + * these functions must be invoked in the right order */
6383 + static oobfunc_T oobfunc[] = {
6386 + {gdb_get_sourcedir},
6388 + {gdb_source_project},
6393 + {gdb_source_list},
6396 + {gdb_stack_frame}, /* after gdb_info_frame */
6397 + {get_lastbp}, /* after gdb_get_frame */
6398 + {gdb_get_asmfunc}, /* after get_lastbp */
6399 + {gdb_get_asmfunc_hack}, /* after gdb_get_asmfunc */
6400 + {gdb_get_asm}, /* after gdb_get_asmfunc */
6401 + {get_bp}, /* after gdb_get_asm and get_lastbp */
6407 + /** Send a cmd to gdb */
6409 + gdb_docmd_cli(this, cmd)
6411 + char_u *cmd; /* gdb cmd */
6413 + # ifdef GDB_LVL3_SUPPORT
6414 + char_u *expression = NULL;
6422 + /* make a copy so we can mess with it */
6425 + this->cmd_type = CMD_ANY;
6428 + cmd = (char_u *)clewn_strsave((char *)cmd);
6430 + /* remove illegal characters */
6431 + for (ptr = last = cmd; *last != NUL; last++)
6434 + || *last == KEY_INTERUPT
6435 + || !iscntrl((int)(*last)))
6439 + /* remove backslash at last position */
6440 + if (ptr != cmd && *(ptr - 1) == '\\')
6443 + if (this->cli_cmd.state == CS_QUERY || this->note == ANO_QUERY)
6450 + /* now we can forget last cmd */
6451 + this->cmd_type = CMD_ANY;
6453 + /* an interrupt */
6454 + if (STRCHR(cmd, KEY_INTERUPT) != NULL)
6458 + if (STRCHR(cmd, TAB) != NULL)
6460 + gdb_cmd_type(this, cmd); /* get cmd type */
6462 + /* handle completion for all non-gdb commands */
6463 + if (this->cmd_type == CMD_RESTART) {
6464 + gdb_setwinput((gdb_handle_T *)this, (char_u *)"cl_restart ");
6466 + this->oob.state &= ~OS_CMD;
6469 + else if (this->cmd_type == CMD_CREATEVAR)
6471 + gdb_setwinput((gdb_handle_T *)this, (char_u *)"createvar ");
6473 + this->oob.state &= ~OS_CMD;
6479 + if ((res = gdb_regexec(cmd, PAT_CHG_ANNO, 0, NULL)) != NULL)
6481 + EMSG(_("Sorry, cannot change annotation level"));
6486 + # ifndef FEAT_GDB /* Clewn follows GDB behavior with empty commands */
6489 + gdb_send_cmd(this, (char_u *)"\n");
6495 + /* process the cmd */
6496 + if ((res = process_cmd(this, cmd)) != NULL)
6501 + # ifdef GDB_LVL3_SUPPORT
6502 + /* a |+gdb| createvar command is processed later in oob varobj_update() */
6503 + if (this->mode == GDB_MODE_LVL3 && this->cmd_type == CMD_CREATEVAR)
6506 + if (this->var_buf == NULL)
6508 + if (this->var_buf <= 0)
6511 + EMSG(_("Variables buffer does not exist anymore: unable to create variable"));
6517 + (expression = gdb_regexec(cmd, PAT_CRVAR_FMT, 2, NULL)) != NULL
6519 + (expression = gdb_regexec(cmd, PAT_CRVAR_FMT, 3, NULL)) != NULL
6521 + && *expression != NUL)
6523 + varobj = (varobj_T *)xcalloc(sizeof(varobj_T));
6525 + /* create a new varobj_T element and link it to the list */
6526 + varobj->state = VS_INIT;
6527 + varobj->children = FALSE;
6529 + varobj->format = gdb_regexec(cmd, PAT_CRVAR_FMT, 1, NULL);
6531 + varobj->format = gdb_regexec(cmd, PAT_CRVAR_FMT, 2, NULL);
6533 + varobj->expression = expression;
6534 + varobj->next = this->lvl3.varlist;
6535 + this->lvl3.varlist = varobj;
6540 + xfree(expression);
6541 + EMSG(_("Unvalid arguments to \"createvar\" command"));
6549 + /* add a newline to cmd if needed */
6550 + len = STRLEN(cmd);
6551 + if (len == 0 || *(cmd + len - 1) != NL)
6554 + gdb_cat(&res, cmd);
6555 + gdb_cat(&res, (char_u *)"\n");
6560 + gdb_send_cmd(this, cmd);
6564 + gdb_send_cmd(this, (char_u *)" \n");
6570 + * Process a gdb cmd according to its type.
6571 + * Return an allocated sanitized cmd or NULL if error.
6574 + process_cmd(this, cmd)
6576 + char_u *cmd; /* user's gdb cmd */
6578 + char_u *delete = NULL;
6579 + char_u *range = NULL;
6583 + buf_T *buf = NULL;
6584 + win_T *oldwin = curwin;
6587 + /* make a copy so we can mess with it */
6588 + if (cmd == NULL || *cmd == NUL)
6590 + cmd = (char_u *)clewn_strsave((char *)cmd);
6592 + gdb_cmd_type(this, cmd); /* get cmd type */
6594 + # ifdef GDB_LVL2_SUPPORT
6595 + /* Replace "createvar" command with GDB "display" command */
6596 + if (this->mode == GDB_MODE_LVL2 && this->cmd_type == CMD_CREATEVAR)
6599 + if ((res = gdb_regexec(cmd, PAT_CREATEVAR, 1, NULL)) != NULL)
6601 + if ((res = gdb_regexec(cmd, PAT_CREATEVAR, 2, NULL)) != NULL)
6605 + this->cmd_type = CMD_DISPLAY;
6607 + gdb_cat(&cmd, (char_u *)"display ");
6608 + gdb_cat(&cmd, res);
6613 + this->cmd_type = CMD_ANY;
6621 + /* Prevent use of a low height size because of "prompt-for-continue" messages.
6622 + * The annotations lines printed by GDB are part of the lines count that
6623 + * is used by GDB for "prompt-for-continue" messages, however we do not
6624 + * display them. */
6625 + if ((res = gdb_regexec(cmd, PAT_HEIGHT, 2, NULL)) != NULL)
6627 + fprintf(stderr, "Cannot change the screen size\n");
6634 + /* Cannot attach to oneself */
6636 + if ((res = gdb_regexec(cmd, PAT_PID, 1, NULL)) != NULL)
6638 + if ((res = gdb_regexec(cmd, PAT_PID, 2, NULL)) != NULL)
6641 + if (getpid() == atoi((char *)res))
6643 + EMSG(_("I refuse to debug myself!"));
6651 + /* no processing for 'define' type cmds */
6652 + if (this->note == ANO_CMDS || this->note == ANO_OVERLOAD)
6655 + switch (this->cmd_type)
6657 + # ifdef GDB_LVL2_SUPPORT
6659 + /* A "display" command without argument is equivalent to the
6660 + * debuggee being stopped */
6661 + if ((res = gdb_regexec(cmd, PAT_DISPLAY, 0, NULL)) != NULL)
6664 + this->cmd_type = CMD_ANY;
6666 + if (this->var_buf != NULL)
6668 + if (this->var_buf > 0)
6670 + this->lvl2.varlist.state = DSP_STOPPED;
6676 + EMSG(_("Sorry, cannot spawn a shell"));
6680 + /* unlite frame on 'detach' */
6682 + gdb_fr_unlite(this);
6685 + /* clear dirty asm buffers */
6688 + for (i = 0; i < this->pool.max; i++)
6690 + if ((curbuf = this->pool.buf[i]) == NULL)
6693 + /* clear the buffer */
6694 + gdb_clear_asmbuf(this, curbuf);
6696 + /* asm buffer is displayed */
6697 + if ((curwin = gdb_btowin(curbuf)) != NULL)
6704 + curbuf = curwin->w_buffer;
6705 + gdb_redraw(buf); /* redraw only if one asm displayed */
6707 + /* unlink all asm buffers */
6711 + # ifdef GDB_LVL3_SUPPORT
6712 + /* get source files list */
6713 + this->lvl3.get_source_list = TRUE;
6718 + # ifdef GDB_LVL3_SUPPORT
6719 + /* get source files list */
6720 + this->lvl3.get_source_list = TRUE;
6725 + case CMD_UP_SILENT:
6727 + case CMD_DOWN_SILENT:
6729 + case CMD_SLECT_FRAME:
6730 + if (this->mode != GDB_MODE_LVL3)
6732 + this->pool.hilite = TRUE;
6734 + /* this should not be necessary but sometimes we
6735 + * don't get the ANO_FRAME_INVALID */
6736 + this->bp_state |= BPS_FR_INVALID;
6742 + /* keep BPS_FR_INVALID state */
6743 + this->bp_state &= BPS_FR_INVALID;
6744 + this->bp_state |= BPS_INVALID;
6747 + /* the restart command is mapped to the gdb 'quit' command,
6748 + * and that will cause gdb to be restarted (the 'quit'
6749 + * command itself is trapped and
6750 + * causes a clean termination of clewn and vim) */
6753 + cmd = (char_u *)clewn_strsave("quit");
6756 + /* terminate clewn and vim */
6758 + this->state |= GS_QUITTING;
6769 + /* Send a cmd to gdb */
6771 + gdb_send_cmd(this, cmd)
6773 + char_u *cmd; /* gdb cmd */
6775 + int do_free = TRUE; /* TRUE when readline must be freed */
6782 + if ( ! GDB_STATE(this, GS_UP))
6785 + this->intr_sent = FALSE;
6787 + /* make a copy so we can mess with it */
6788 + if (cmd == NULL || (len = STRLEN(cmd)) == 0 )
6790 + cmd = (char_u *)clewn_strsave((char *)cmd);
6792 + /* paranoia: trim after NL */
6793 + if ((res = STRCHR(cmd, (int)NL)) != NULL)
6796 + /* answering to a query: any stuff not 'y[es]' is converted to 'no' */
6797 + if (this->cli_cmd.state == CS_QUERY || this->note == ANO_QUERY)
6800 + if ((res = gdb_regexec(cmd, PAT_YES, 0, NULL)) != NULL)
6809 + /* CMD_DIR is acted upon when parsing gdb output */
6810 + if (this->cmd_type != CMD_DIR)
6811 + this->cmd_type = CMD_ANY;
6814 + if (this->cli_cmd.state == CS_QUERY) /* no NL when a completion */
6816 + this->cli_cmd.state = CS_CHOICE;
6819 + /* a standalone <Tab> */
6820 + if (this->cli_cmd.readline == NULL
6821 + && this->cli_cmd.gdb != NULL && *(this->cli_cmd.gdb) == NUL)
6822 + this->oob.state &= ~OS_CMD;
6826 + this->cli_cmd.state = CS_START;
6828 + len = 2; /* enough room since cmd length not zero */
6830 + goto write_answer;
6833 + /* an interrupt */
6834 + if (STRCHR(cmd, KEY_INTERUPT) != NULL)
6836 + this->intr_sent = TRUE;
6837 + this->cli_cmd.state = CS_START;
6838 + goto write_answer;
6841 + /* a cmd following a completion response by gdb */
6842 + if (this->cli_cmd.state == CS_DONE && this->cli_cmd.readline != NULL)
6844 + /* readline matches start of cmd: send 'user cmd - readline' */
6845 + if (STRSTR(cmd, this->cli_cmd.readline) == cmd)
6847 + offset = STRLEN(this->cli_cmd.readline);
6854 + /* send KEY_KILL to erase gdb's readline */
6855 + gdb_buf[0] = KEY_KILL;
6856 + write(this->fd, gdb_buf, 1);
6858 + /* discard gdb answer:
6859 + * '\r' plus the termcap entry 'ce' (clear to end of line) */
6860 + l = gdb_read(this, (char_u *)gdb_buf, MAX_BUFFSIZE, 1000);
6862 + /* do what the discarded stuff above was meant to do:
6863 + * replace last line by getting rid of readline */
6864 + /* find the rightmost match */
6866 + for (start = this->line; *start != NUL; start++)
6867 + if ((start = STRSTR(start, this->cli_cmd.readline)) != NULL)
6875 + gdb_write_buf(this, this->line, FALSE);
6877 + FREE(this->cli_cmd.echoed);
6881 + this->cli_cmd.state = CS_START;
6883 + /* a completion request */
6884 + if (*(cmd + offset + len - 1) == TAB)
6886 + this->cli_cmd.state = CS_PENDING;
6888 + xfree(this->cli_cmd.gdb);
6889 + this->cli_cmd.gdb = (char_u *)clewn_strsave((char *)(cmd + offset));
6890 + *(this->cli_cmd.gdb + len - 1) = NUL; /* remove <Tab> */
6894 + FREE(this->cli_cmd.readline);
6895 + write(this->fd, (char *)cmd + offset, len);
6901 + # if defined(MACOS_X) || defined(MACOS_X_UNIX)
6902 + /* Strip terminating carriage return from a line */
6907 + int len = STRLEN(line);
6909 + if (len != 0 && line[len - 1] == '\r')
6910 + line[len - 1] = NUL;
6916 + /* Handle "prompt-for-continue" annotations.
6917 + * This is not needed by VimGDB as the screen height is very large. */
6918 + # define MANAGE_PRMPT_FORMORE
6920 + /* The fix for writing through readline the concatenation of multiple
6921 + * lines output by gdb, is only correctly implemented for clewn */
6922 + # define FIX_CONCATENATION_WRITE
6925 + * Parse gdb output for annotation and completion. Update gdb console.
6926 + * Return TRUE when the user must be prompted by the input-line window.
6929 + gdb_parse_output_cli(this)
6932 + # ifdef FIX_CONCATENATION_WRITE
6933 + static int pending_write = FALSE; /* TRUE, this->line content has not been written yet */
6935 + struct obstack obs; /* use an obstack for temporary allocated memory */
6942 + # ifdef MANAGE_PRMPT_FORMORE
6946 + /* read gdb data */
6947 + if (this == NULL || ! GDB_STATE(this, GS_UP)
6948 + || gdb_read(this, (char_u *)gdb_buf, MAX_BUFFSIZE, 0) <= 0)
6951 + (void)obstack_init(&obs);
6953 + /* Process line after line */
6954 + for (start = end = (char_u *)gdb_buf; end != NULL; start = end)
6956 + /* Get next line */
6957 + if ((end = STRCHR(start, NL)) != NULL)
6959 + else if (*start == NUL) /* nothing left to read */
6962 + /* concatenate with incomplete annotation */
6963 + if (this->annotation != NULL)
6965 + obstack_strcat(&obs, this->annotation);
6966 + obstack_strcat0(&obs, start);
6967 + line = (char_u *)obstack_finish(&obs);
6970 + line = obstack_strsave(&obs, start);
6973 + # if defined(MACOS_X) || defined(MACOS_X_UNIX)
6978 + /* With GDB 6.0, completion giving as a result a long list of items causes
6979 + * a "--More--" prompt to be issued after what GDB (or readline) considers
6980 + * the height of the terminal (unfortunately not using the GDB height
6981 + * settings). In case we could not size the terminal to a very big height
6982 + * with an ioctl call in exec_gdb(), we must answer to the prompt. */
6983 + if (this->height == 0 /* height not set */
6984 + && this->cli_cmd.state == CS_CHOICE /* a completion list */
6986 + && STRCMP(line, "--More--") == 0) /* standalone prompt */
6988 + write(this->fd, " ", 1); /* prompt for more */
6989 + this->annoted = FALSE;
6993 + # ifdef FEAT_GDB /* Clewn does not use hiliting */
6994 + /* some fuzzy gdb annotation corner: rewrite '(gdb) Quit' so that
6995 + * it gets highlited (must be done before the newline stuff) */
6996 + if (parse_note(this, line) != NULL && this->note == ANO_QUIT)
6997 + gdb_write_buf(this, this->line, FALSE);
7000 + /* two consecutive NL: start a new line except when this annotation
7001 + * just follows another annotation
7002 + * IS_ANNOTATION() does not handle a standalone '\032' */
7003 + if (this->newline && (*line != '\032' || !this->annoted))
7005 + # ifdef MANAGE_PRMPT_FORMORE
7006 + do_newline = TRUE;
7008 + /* do not start a new line when parsing annotations and
7009 + * . the next chunk is a "pre-prompt-for-continue" and
7010 + * the previous chunk was an annotation
7011 + * . or this is a "pre-prompt-for-continue" annotation */
7012 + if (this->mode == GDB_MODE_LVL2
7013 + && ! IS_OOBACTIVE(this) && (this->state & GS_ANO))
7015 + if (end != NULL && get_note(this, end) == ANO_PREPMT_FORMORE
7016 + && this->prev_note != ANO_NONE)
7017 + do_newline = FALSE;
7018 + if (line != NULL && get_note(this, line) == ANO_PREPMT_FORMORE)
7019 + do_newline = FALSE;
7025 + if (this->line == NULL && *line != '\032')
7027 + if (IS_OOBACTIVE(this))
7028 + gdb_oob_receive(this, (char_u *)"", &obs);
7030 + gdb_write_buf(this, (char_u *)"", TRUE);
7033 + # ifdef FIX_CONCATENATION_WRITE
7034 + if (pending_write)
7035 + gdb_write_buf(this, this->line, TRUE);
7038 + FREE(this->line); /* start a new line */
7039 + this->note = ANO_NONE;
7042 + this->newline = FALSE;
7044 + /* Parse for annotations */
7045 + /* we cannot parse "\n\032\032annotation\n" directly
7046 + * as any stuff may be split across two buff read;
7047 + * must concatenate line when interleaved with annotations */
7050 + /* ignore echoed NL after ANO_PMT_FORMORE msg */
7051 + if (this->note != ANO_PMT_FORMORE)
7052 + this->newline = TRUE;
7054 + # ifdef MANAGE_PRMPT_FORMORE
7055 + /* start a new line */
7056 + if (this->mode == GDB_MODE_LVL2 && this->prev_note == ANO_POSTPMT_FORMORE)
7059 + this->note = ANO_NONE;
7063 + /* a complete annotation */
7064 + else if (IS_ANNOTATION(line) && end != NULL)
7066 + /* remember last annotation type */
7067 + if (this->note != ANO_PREPMT_FORMORE
7068 + && this->note != ANO_PMT_FORMORE
7069 + && this->note != ANO_POSTPMT_FORMORE)
7070 + this->valid_note = this->note;
7072 + res = parse_note(this, line); /* assert != NULL */
7074 + if ((res = process_annotation(this, res, &obs)) != NULL)
7076 + gdb_setwinput((gdb_handle_T *)this, res);
7079 + /* fake an interrupt: will empty stuff and typeahead
7080 + * buffers aborting insert mode, pending mappings
7081 + * and operations */
7085 + FREE(this->annotation);
7086 + this->annoted = TRUE;
7088 + # ifdef GDB_LVL2_SUPPORT
7089 + /* ANO_DISP_END has no content and must be trapped here */
7092 + this->mode == GDB_MODE_LVL2 && this->var_buf != NULL
7094 + this->mode == GDB_MODE_LVL2 && this->var_buf > 0
7096 + && this->note == ANO_DISP_END)
7098 + gdb_process_display(this, (char_u *)"", &obs);
7102 + # ifdef MANAGE_PRMPT_FORMORE
7103 + /* start a new line when end of annotation list or table */
7104 + if (this->mode == GDB_MODE_LVL2
7105 + && this->prev_note == ANO_POSTPMT_FORMORE
7106 + && (this->note == ANO_BP_TABLE
7107 + || this->note == ANO_BP_RECORD
7108 + || this->note == ANO_BP_END
7109 + || this->note == ANO_FRAME_END
7110 + || this->note == ANO_DISP_END))
7112 + FREE(this->line); /* start a new line */
7113 + this->note = ANO_NONE;
7117 + /* store current annotation type */
7118 + this->prev_note = this->note;
7120 + /* restore annotation type */
7121 + if (this->note == ANO_POSTPMT_FORMORE)
7122 + this->note = this->valid_note;
7124 + /* a partial annotation */
7125 + else if (*line == '\032'
7126 + && (*(line + 1) == NUL || *(line + 1) == '\032')
7129 + xfree(this->annotation);
7130 + this->annotation = (char_u *)clewn_strsave((char *)line);
7135 + # ifdef MANAGE_PRMPT_FORMORE
7136 + /* The breakpoint table:
7137 + * start a new line when line starts with <TAB>.*/
7138 + if (this->mode == GDB_MODE_LVL2
7139 + && this->prev_note == ANO_POSTPMT_FORMORE
7140 + && line != NULL && *line == TAB)
7142 + FREE(this->line); /* start a new line */
7143 + this->note = ANO_NONE;
7147 + if (this->note == ANO_PREPMT_FORMORE)
7149 + # ifdef MANAGE_PRMPT_FORMORE
7150 + if (! IS_OOBACTIVE(this))
7152 + /* Starting with GDB 6.0, GDB sends an ANO_PREPMT_FORMORE
7153 + * whenever ^C have been typed more that gdb_screen_height/2. */
7154 + if (this->state & GS_ANO || this->intr_sent)
7156 + write(this->fd, "\n", 1); /* prompt for more */
7160 + this->oob.state &= ~OS_CMD; /* enable next command */
7161 + xfree(this->prompt);
7163 + this->prompt = (char_u *)clewn_strsave((char *)line);
7165 + this->prompt = (char_u *)clewn_strsave(
7166 + "---type <return> to continue, or q <return> to quit---");
7168 + this->intr_sent = FALSE;
7171 + line = NULL; /* remove ANO_PMT_FORMORE msg */
7174 + # ifdef GDB_LVL2_SUPPORT
7175 + /* handle a display annotation content
7176 + * take care of nested structures and arrays in value content */
7178 + if (this->mode == GDB_MODE_LVL2 && this->var_buf != NULL)
7180 + if (this->mode == GDB_MODE_LVL2 && this->var_buf > 0)
7183 + if ((this->note >= ANO_DISP_BEG && this->note <= ANO_DISP_END)
7184 + || (this->lvl2.doing_value && this->note >= ANO_FIELD_BEG
7185 + && this->note <= ANO_FIELD_END)
7186 + || (this->lvl2.doing_value && this->note >= ANO_ARRAY_BEG
7187 + && this->note <= ANO_ARRAY_END))
7189 + gdb_process_display(this, line, &obs);
7195 + if (IS_OOBACTIVE(this))
7197 + gdb_oob_receive(this, line, &obs);
7201 + if (this->note == ANO_PROMPT || this->note == ANO_CMDS)
7202 + gdb_cat(&(this->cli_cmd.echoed), line);
7204 + /* update line cnt before doing cpltn */
7205 + if (this->line == NULL || !this->annoted)
7206 + this->cli_cmd.cnt++;
7208 + /* Parse for completion */
7209 + if ((res = process_completion( &(this->cli_cmd), line, &obs)) != NULL)
7211 + gdb_setwinput((gdb_handle_T *)this, res);
7216 + if (line != NULL && (len = STRLEN(line)) != 0
7217 + && *(line + len - 1) == BELL)
7218 + *(line + len - 1) = NUL;
7220 + /* concatenate after an annotation and replace, otherwise add */
7221 + if (this->line != NULL && this->annoted)
7223 + if (this->note == ANO_ERROR_BEG && STRCMP(line, "Quit") == 0)
7224 + this->syntax = TRUE;
7226 + obstack_strcat(&obs, this->line);
7227 + obstack_strcat0(&obs, line);
7228 + line = (char_u *)obstack_finish(&obs);
7230 + # ifndef FEAT_GDB /* do not write "(gdb) Quit" with Clewn (already done) */
7231 + if (this->note != ANO_ERROR_BEG)
7234 + # ifdef FIX_CONCATENATION_WRITE
7235 + /* write a complete line */
7238 + if (pending_write)
7239 + gdb_write_buf(this, line, TRUE);
7241 + gdb_write_buf(this, line, FALSE);
7244 + gdb_write_buf(this, line, FALSE);
7251 + # ifdef FEAT_GDB /* no need to map T_CE when running Clewn */
7252 + /* a completion list */
7253 + if (this->height == 0 /* height not set */
7254 + && this->cli_cmd.state == CS_CHOICE)
7258 + /* discard "^\rT_CE\r" which is sent by readline
7259 + * after answering to a prompt in a completion list
7260 + * (not needed on systems where TIOCSWINSZ ioctls are
7262 + if (STRSTR(line, T_CE) == line + 1
7263 + && STRLEN(line) >= STRLEN(T_CE) + 2)
7265 + ptr = line + STRLEN(T_CE) + 2;
7266 + line = obstack_strsave(&obs, ptr);
7269 + gdb_write_buf(this, line, TRUE);
7271 + /* do not write the query prompt */
7272 + if (this->cli_cmd.state == CS_QUERY)
7273 + gdb_write_buf(this, (char_u *)"", TRUE);
7276 + # ifdef FIX_CONCATENATION_WRITE
7277 + /* write a complete line */
7280 + gdb_write_buf(this, line, TRUE);
7283 + gdb_write_buf(this, line, TRUE);
7289 + xfree(this->line);
7290 + this->line = (line != NULL ? (char_u *)clewn_strsave((char *)line) : NULL);
7293 + # ifdef FIX_CONCATENATION_WRITE
7294 + pending_write = FALSE;
7295 + if (end == NULL) /* incomplete line */
7297 + pending_write = TRUE;
7298 + this->annoted = TRUE; /* force concatenation on next read */
7302 + if (end == NULL) /* incomplete line */
7304 + this->annoted = TRUE; /* force concatenation on next read */
7308 + this->annoted = FALSE;
7309 + this->note = ANO_NONE;
7313 + obstack_free(&obs, NULL);
7315 + if (IS_OOBACTIVE(this))
7319 + /* redraw gdb console window when displayed */
7320 + gdb_redraw(this->buf);
7323 + /* Wait till we get the prompt to send the first cmd */
7324 + if (this->firstcmd != NULL && this->note == ANO_PROMPT)
7326 + gdb_docmd((gdb_handle_T *)this, this->firstcmd);
7327 + FREE(this->firstcmd);
7330 + if ((rc = gdb_iswinput((gdb_handle_T *)this)) == TRUE)
7331 + this->oob.state &= ~OS_CMD;
7336 + * Process an annotation.
7337 + * Return cmd to prompt the user with or NULL if none.
7340 + process_annotation(this, str, obs)
7342 + char_u *str; /* annotation's content */
7343 + struct obstack *obs;
7345 + int s_a = (this->state & GS_ALLOWED);
7346 + char_u *file = NULL;
7347 + char_u *line = NULL;
7348 + linenr_T linenumber;
7353 + this->syntax = FALSE;
7354 + this->parser = PS_ANY;
7356 + switch (this->note)
7358 + /* Output end: run directory function */
7359 + case ANO_PREPROMPT:
7360 + this->syntax = TRUE;
7361 + this->parser = PS_PREPROMPT;
7362 + this->cmd_type = CMD_ANY;
7363 + this->state &= ~GS_ANO;
7366 + /* Send out of band cmd */
7368 + this->syntax = TRUE;
7369 + this->parser = PS_PROMPT;
7370 + this->cli_cmd.cnt = 1;
7371 + FREE(this->cli_cmd.echoed);
7372 + # ifndef FEAT_GDB /* store the prompt */
7373 + if (! IS_OOBACTIVE(this) || (this->oob.state & OS_INTR))
7375 + xfree(this->prompt);
7376 + if (this->line != NULL)
7377 + this->prompt = (char_u *)clewn_strsave((char *)this->line);
7379 + this->prompt = (char_u *)clewn_strsave("(gdb) ");
7382 + if (this->cli_cmd.state == CS_START) {
7383 + gdb_oob_send(this, obs);
7385 + /* reset the standard oobfunc table after invocation
7386 + * of a one function oobfunc array */
7387 + this->oobfunc = this->std_oobfunc;
7392 + this->syntax = TRUE;
7393 + this->cli_cmd.cnt = 1;
7394 + this->oob.state &= ~OS_CMD;
7395 + FREE(this->cli_cmd.echoed);
7396 + # ifndef FEAT_GDB /* store the prompt */
7397 + if (! IS_OOBACTIVE(this) || (this->oob.state & OS_INTR))
7399 + xfree(this->prompt);
7400 + if (this->line != NULL)
7401 + this->prompt = (char_u *)clewn_strsave((char *)this->line);
7403 + this->prompt = (char_u *)clewn_strsave("> ");
7407 + /* should be in process_completion, but bug in gdb
7408 + * annotations where 'pre-commands' is missing in completions */
7409 + if (this->cli_cmd.state == CS_CHOICE
7410 + && (cpn = eol_choices(&(this->cli_cmd), obs)) != NULL)
7413 + /* a lone <Tab> does not prompt the user except in define mode */
7414 + if ((this->cli_cmd.state != CS_PENDING
7415 + && this->cli_cmd.state != CS_CHOICE)
7416 + || (this->cli_cmd.readline == NULL && this->cli_cmd.gdb != NULL
7417 + && *(this->cli_cmd.gdb) == NUL))
7418 + return (char_u *)clewn_strsave("");
7421 + case ANO_OVERLOAD:
7423 + this->oob.state &= ~OS_CMD;
7424 + # ifndef FEAT_GDB /* store the prompt */
7425 + if (! IS_OOBACTIVE(this) || (this->oob.state & OS_INTR))
7427 + xfree(this->prompt);
7428 + if (this->line != NULL)
7429 + this->prompt = (char_u *)clewn_strsave((char *)this->line);
7431 + this->prompt = (char_u *)clewn_strsave("> ");
7434 + return (char_u *)clewn_strsave("");
7436 + case ANO_PMT_FORMORE:
7437 + # ifndef FEAT_GDB /* handle ANO_PMT_FORMORE when IS_OOBACTIVE */
7438 + if (IS_OOBACTIVE(this))
7441 + if (this->oob.state & OS_INTR)
7444 + gdb_send_cmd(this, (char_u *)"q\n"); /* abort */
7447 + gdb_send_cmd(this, (char_u *)"\n"); /* get more lines */
7452 + this->syntax = TRUE;
7453 + this->oob.state |= OS_QUIT;
7456 + case ANO_ERROR_BEG:
7457 + this->pool.hilite = FALSE;
7458 + # ifdef GDB_LVL2_SUPPORT
7459 + /* a display expression parse error */
7460 + this->lvl2.doing_value = FALSE;
7461 + FREE(this->lvl2.dentry.num);
7462 + FREE(this->lvl2.dentry.expression);
7463 + FREE(this->lvl2.dentry.value);
7465 + # ifdef GDB_LVL3_SUPPORT
7466 + if (this->lvl3.varitem != NULL)
7467 + this->lvl3.varitem->state |= VS_ERROR;
7471 + case ANO_STARTING:
7472 + this->frame_curlvl = -1;
7473 + this->frame_lnum = (linenr_T) -1;
7474 + FREE(this->frame_fname);
7476 + FREE(this->frame_pc);
7477 + this->state &= ~GS_STOPPED;
7478 + gdb_status(this, (char_u *)"running...", obs);
7480 + if (this->mode == GDB_MODE_LVL3)
7482 + this->pool.hilite = FALSE;
7483 + if (p_asm != 0 && this->cmd_type == CMD_STEPI) /* asm frame highlite: when stepi nexti */
7484 + this->pool.hilite = TRUE;
7488 + this->pool.hilite = TRUE;
7490 + case ANO_FRAME_INVALID:
7491 + gdb_fr_unlite(this);
7492 + this->bp_state |= BPS_FR_INVALID;
7495 + case ANO_BP_INVALID:
7496 + /* keep BPS_FR_INVALID state */
7497 + this->bp_state &= BPS_FR_INVALID;
7498 + this->bp_state |= BPS_INVALID;
7500 + /* note the fact that the user is setting a
7502 + if (p_asm != 0 && this->cmd_type == CMD_BREAK)
7503 + this->bp_state |= BPS_BP_SET;
7507 + this->state |= GS_STOPPED;
7508 + gdb_status(this, (char_u *)"stopped", obs);
7509 + # ifdef GDB_LVL2_SUPPORT
7511 + if (this->var_buf != NULL)
7513 + if (this->var_buf > 0)
7515 + this->lvl2.varlist.state = DSP_STOPPED;
7520 + case ANO_SIGNALLED:
7521 + FREE(this->frame_pc);
7523 + this->state |= GS_STOPPED;
7524 + gdb_status(this, (char_u *)"exited", obs);
7527 + /* remove phantom highlite */
7528 + gdb_unlite(PHANTOM_SIGN);
7532 + /* Breakpoint hit */
7533 + case ANO_BREAKPOINT:
7534 + /* Look for this breakpoint in bpinfo list */
7535 + if (str != NULL && (bp_number = atoi((char *)str)) > 0)
7537 + for (r = this->bpinfo; r != NULL; r = r->next)
7539 + if (r->id == bp_number)
7541 + /* Set this->cont TRUE if this breakpoint's 'commands'
7542 + * includes a 'continue' as last statement */
7544 + this->cont = TRUE;
7546 + # ifdef BP_INVALID_ANO_MISSING
7547 + /* Trigger get_bp(): the breakpoint we hit is
7548 + * 'enable once' */
7549 + if (r->enabled && ! r->disposition)
7551 + /* keep BPS_FR_INVALID state */
7552 + this->bp_state &= BPS_FR_INVALID;
7553 + this->bp_state |= BPS_INVALID | BPS_BP_HIT;
7560 + /* Not found in the list. An asm buffer holding this bp
7561 + * can possibly be disassembled next by oob get_asm().
7562 + * Trigger oob get_bp() */
7563 + if (r == NULL && p_asm != 0)
7565 + /* keep BPS_FR_INVALID state */
7566 + this->bp_state &= BPS_FR_INVALID;
7567 + this->bp_state |= BPS_INVALID | BPS_BP_HIT;
7572 + # ifdef GDB_LVL2_SUPPORT
7574 + /* gdb stats the file when doing ANO_SOURCE, so we can't rely on
7575 + * that annotation for remote debugging with clewn when the source
7576 + * files are on the host and not on the target
7577 + * => use ANO_BREAKPOINT instead in level 3
7580 + if (! IS_OOBACTIVE(this) && this->mode == GDB_MODE_LVL2)
7582 + /* Uncomment next line to print source text in gdb buffer */
7583 + /* gdb_write_buf(this, str, TRUE); */
7586 + gdb_popup_console(this);
7589 + this->pool.hilite = FALSE;
7591 + /* asm frame highlite: when stepi nexti */
7592 + if (p_asm != 0 && this->cmd_type == CMD_STEPI)
7593 + this->pool.hilite = TRUE;
7596 + /* prevent recursive calls to parse_output() since breakpoint
7597 + * or frame highlighting may cause Vim to query the user when
7598 + * changes have been made in the previous buffer */
7599 + this->state &= ~GS_ALLOWED;
7601 + if ((line = gdb_regexec(str, PAT_SOURCE, 2, obs)) != NULL)
7603 + file = gdb_regexec(str, PAT_SOURCE, 1, obs);
7604 + linenumber = atoi((char *)line);
7605 + gdb_fr_set(this, file, &linenumber, obs);
7608 + this->state &= ~GS_ALLOWED;
7610 + this->state |= GS_ALLOWED;
7615 + case ANO_FRAME_BEGIN:
7616 + case ANO_BP_HEADER:
7617 + case ANO_DISP_BEG:
7618 + this->state |= GS_ANO;
7621 + case ANO_FRAME_END:
7622 + case ANO_DISP_END:
7625 + /* Get the source for this frame */
7626 + case ANO_BP_RECORD:
7627 + this->bp_state |= BPS_RECORD;
7628 + this->bp_state |= BPS_START;
7631 + case ANO_BP_FIELD0:
7632 + case ANO_BP_FIELD1:
7633 + case ANO_BP_FIELD2:
7634 + case ANO_BP_FIELD3:
7635 + case ANO_BP_FIELD4:
7636 + case ANO_BP_FIELD5:
7637 + case ANO_BP_FIELD6:
7638 + case ANO_BP_FIELD7:
7639 + case ANO_BP_FIELD8:
7640 + case ANO_BP_FIELD9:
7641 + this->bp_state = SET_RECORD_IDX(this->bp_state,
7642 + (this->note - ANO_BP_FIELD0) + BI_NUM);
7646 + /* Initialize state but do not forget some of them.
7647 + * ANO_BP_END can be the one we get when fetching the
7648 + * table with oob function get_lastbp(): get_bp() still
7649 + * needs those states */
7650 + this->bp_state &= (BPS_INVALID | BPS_BP_HIT | BPS_FR_INVALID);
7658 + * Parse gdb output for completion.
7659 + * Return cmd to prompt the user with or NULL if none.
7662 + process_completion(cmd, line, obs)
7664 + char_u *line; /* line to parse */
7665 + struct obstack *obs;
7671 + if (line == NULL || *line == NUL)
7674 + switch (cmd->state)
7677 + /* A completion query */
7678 + if (cmd->cnt == 2 && gdb_regexec(line, PAT_QUERY, 0, obs) != NULL)
7680 + cmd->state = CS_QUERY;
7681 + return (char_u *)clewn_strsave("");
7684 + /* A positive completion */
7685 + if (cmd->cnt == 1 && cmd->echoed != NULL
7686 + && (len = (cmd->gdb != NULL ? STRLEN(cmd->gdb) : 0)) > 0)
7688 + /* find the rightmost match */
7690 + for (start = cmd->echoed; *start != NUL; start++)
7691 + if ((start = STRSTR(start, cmd->gdb)) != NULL)
7696 + /* strictly greater and not followed by NL */
7697 + if (res != NULL && *(res + len) != NL
7698 + && cmd->echoed + STRLEN(cmd->echoed) > res + len)
7700 + if (*(res + len) == BELL)
7703 + *(res + len) = NUL;
7705 + xfree(cmd->readline);
7706 + cmd->readline = (char_u *)clewn_strsave((char *)cmd->echoed);
7707 + cmd->state = CS_DONE;
7708 + return (char_u *)clewn_strsave((char *)cmd->readline);
7712 + /* A BELL: first character */
7713 + if (cmd->cnt == 1 && *line == BELL)
7717 + cmd->state = CS_DONE;
7718 + return (cmd->readline != NULL ?
7719 + (char_u *)clewn_strsave((char *)cmd->readline) : NULL);
7723 + cmd->state = CS_CHOICE;
7727 + /* The end of a list of completion choices */
7728 + if (cmd->cnt == 1 && (res = eol_choices(cmd, obs)) != NULL)
7736 + * The end of a list of completion choices.
7737 + * Return cmd to prompt the user with.
7740 + eol_choices(cmd, obs)
7742 + struct obstack *obs;
7746 + obstack_strcat(obs, cmd->readline);
7747 + obstack_strcat0(obs, cmd->gdb);
7748 + new = (char_u *)obstack_finish(obs);
7750 + /* a match with the new readline */
7751 + if (cmd->echoed != NULL && STRSTR(cmd->echoed, new) == cmd->echoed)
7753 + xfree(cmd->readline);
7754 + cmd->readline = (char_u *)clewn_strsave((char *)cmd->echoed);
7755 + cmd->state = CS_DONE;
7756 + return (char_u *)clewn_strsave((char *)cmd->echoed);
7761 + # ifdef GDB_LVL3_SUPPORT
7762 + /* Initialize the gdb_T structure lvl3 component that lvl3 is responsible for */
7767 + varobj_T *item, *next;
7771 + FREE(this->lvl3.result);
7773 + this->lvl3.get_source_list = TRUE;
7774 + FREE(this->lvl3.source_cur);
7775 + FREE(this->lvl3.source_list);
7777 + for (item = this->lvl3.varlist; item != NULL; item = next)
7779 + next = item->next;
7780 + xfree(item->name);
7781 + xfree(item->format);
7782 + xfree(item->expression);
7785 + this->lvl3.varlist = NULL;
7786 + this->lvl3.varitem = NULL;
7790 + /* Initialize lvl3 function pointers */
7792 + gdb_lvl3_init(this)
7795 + this->mode = GDB_MODE_LVL3;
7796 + this->oobfunc = oobfunc;
7797 + this->std_oobfunc = oobfunc;
7798 + this->parse_output = gdb_parse_output_cli;
7799 + this->gdb_docmd = gdb_docmd_cli;
7800 + this->var_delete = NULL;
7801 + this->clear_gdb_T = clear_gdb_T;
7803 + # endif /* GDB_LVL3_SUPPORT */
7806 + # define SG_INTRO_2 "Vim |+gdb| level 2 mode\n\n"
7807 + # define SG_INTRO_3 "Vim |+gdb| level 3 mode\n\n"
7809 + # define SG_INTRO_2 "... \
7810 + \n... Clewn running GDB in level 2 mode\n...\n"
7811 + # define SG_INTRO_3 "... \
7812 + \n... Clewn %s running GDB in level 3 mode\n...\n"
7814 + # define SG_INTERP "server interpreter-exec mi -gdb-version\n"
7815 + # define SG_LVL_2 "server set annotate 2\n"
7816 + # define SG_LVL_3 "server set annotate 3\n"
7817 + # define SG_HEIGHT "server set height "
7818 + # define SG_WIDTH "server set width 0\n "
7819 + # define SG_EDITING "server set editing on\n"
7820 + # define SG_VERSION "server show version\n"
7822 + /* SG_TIMEOUT must be quite big as we may have Clewn, Vim and GDB all
7823 + * starting at the same time. Unless things go pretty bad in the parsing, we
7824 + * always find the needle, so the user never wait SG_TIMEOUT. */
7825 + # define SG_TIMEOUT 120000 /* msecs for when the needle cannot be found */
7827 + * Initialize gdb CLI (command line interface)
7828 + * return OK when sucess, FAIL otherwise
7831 + gdb_setup_cli(this)
7835 + int needle = FALSE; /* defines when we can start writing to gdb console */
7836 + int gdb_cnt = 0; /* count of received "(gdb)" prompts */
7837 + int lvl3_mode = FALSE; /* level */
7838 + char_u *buff = (char_u *)gdb_buf;/* can't add an int to the reference to an array */
7839 + char * tty_name = NULL;
7845 + char_u *lpp_lines;
7849 + this->note = ANO_NONE;
7851 + /* Does this GDB process supports "interpreter-exec" command ?
7852 + * if yes we will use level 3 mode, otherwise level 2 mode */
7853 + write(this->fd, SG_INTERP, strlen(SG_INTERP));
7855 + /* discard gdb output till we find the needle SG_VERSION
7856 + * MAX_BUFFSIZE must be greater than max gdb line length */
7857 + for (last = (char_u *)gdb_buf; buff + MAX_BUFFSIZE - last > 1; )
7859 + if ((len = gdb_read(this, last,
7860 + buff + MAX_BUFFSIZE - last, SG_TIMEOUT)) < 0)
7862 + err = "Unable to read from GDB pseudo tty";
7865 + else if (len == 0) /* needle not found */
7869 + ptr = (char_u *)gdb_buf;
7871 + /* First step: determine which level, process line by line */
7880 + if (STRSTR(ptr, "^done") == ptr)
7883 + /* the first prompt is newline terminated (count it only once) */
7884 + if (STRSTR(ptr, "(gdb) ") == ptr
7885 + && (gdb_cnt == 1 || STRCHR(ptr, NL) != NULL))
7890 + # ifdef GDB_LVL3_SUPPORT
7891 + /* set annotation level 3 */
7893 + write(this->fd, SG_LVL_3, strlen(SG_LVL_3));
7895 + # ifdef GDB_LVL2_SUPPORT
7896 + write(this->fd, SG_LVL_2, strlen(SG_LVL_2));
7899 + err = "This |+gdb| version does not support level 2 mode";
7904 + lvl3_mode = FALSE;
7905 + # ifdef GDB_LVL2_SUPPORT
7906 + /* set annotation level 2 */
7908 + write(this->fd, SG_LVL_2, strlen(SG_LVL_2));
7910 + # endif /* LVL3 */
7912 + # ifdef FEAT_GDB /* Clewn does not need this */
7913 + /* ANO_PMT_FORMORE happen every LPP_LINES and provide us a mean to abort
7914 + * large output (in get_asm for example or any user cmd) */
7915 + write(this->fd, SG_HEIGHT, strlen(SG_HEIGHT));
7916 + lpp_lines = gdb_itoa(LPP_LINES);
7917 + write(this->fd, (char *)lpp_lines, strlen((char *)lpp_lines));
7918 + write(this->fd, "\n", 1);
7919 + write(this->fd, SG_WIDTH, strlen(SG_WIDTH));
7920 + write(this->fd, SG_EDITING, strlen(SG_EDITING));
7922 + /* number of lines in a page is unlimited */
7923 + write(this->fd, SG_HEIGHT, strlen(SG_HEIGHT));
7924 + lpp_lines = gdb_itoa(0);
7925 + write(this->fd, lpp_lines, strlen(lpp_lines));
7926 + write(this->fd, "\n", 1);
7927 + write(this->fd, SG_WIDTH, strlen(SG_WIDTH));
7928 + write(this->fd, SG_EDITING, strlen(SG_EDITING));
7929 + write(this->fd, " \n", 2); /* avoid Undefined command: "server". Try "help". */
7931 + /* `run' commands do input and output on clewn own terminal when possible */
7932 + if (isatty(1) && (tty_name=ttyname(1)) != NULL) {
7933 + char_u * res = NULL;
7935 + gdb_cat(&res, (char_u *)"server tty ");
7936 + gdb_cat(&res, tty_name);
7937 + gdb_cat(&res, (char_u *)"\n");
7938 + write(this->fd, res, STRLEN(res));
7942 + write(this->fd, SG_VERSION, strlen(SG_VERSION));
7944 + } while ((ptr = STRCHR(ptr, NL)) != NULL);
7946 + /* Second step: find the needle, process line by line */
7955 + /* looking for the needle after a prompt */
7956 + if (this->note == ANO_PROMPT && STRSTR(ptr, SG_VERSION) == ptr)
7958 + ptr += strlen(SG_VERSION);
7962 + /* discard post-prompt */
7963 + if (needle && this->note == ANO_POSTPROMPT)
7965 + /* store a partial last line for later parse_output */
7966 + if ((line = (char_u *)strrchr(gdb_buf, (int)NL)) != NULL
7967 + && *(line + 1) != NUL)
7969 + xfree(this->line);
7970 + this->line = (char_u *)clewn_strsave((char *)(line + 1));
7971 + this->annoted = TRUE;
7975 + # ifdef GDB_LVL3_SUPPORT
7978 + gdb_popup_console(this);
7981 + this->syntax = TRUE; /* force syntax highlite */
7983 + gdb_write_buf(this, (char_u *)SG_INTRO_3, TRUE);
7985 + sprintf(tmp, SG_INTRO_3, this->version);
7986 + gdb_write_buf(this, tmp, TRUE);
7988 + this->syntax = FALSE;
7990 + # ifdef FEAT_GDB /* write unconditionally with Clewn */
7991 + /* write the remaining part and display it */
7994 + gdb_write_buf(this, ptr, TRUE);
7997 + /* redraw gdb console window when displayed */
7998 + gdb_redraw(this->buf);
8001 + gdb_lvl3_init(this);
8005 + err = "This |+gdb| version does not support level 3 mode";
8010 + # ifdef GDB_LVL2_SUPPORT
8013 + gdb_popup_console(this);
8016 + this->syntax = TRUE; /* force syntax highlite */
8017 + gdb_write_buf(this, (char_u *)SG_INTRO_2, TRUE);
8018 + this->syntax = FALSE;
8020 + # ifdef FEAT_GDB /* write unconditionally with Clewn */
8021 + /* write the remaining part and display it */
8024 + gdb_write_buf(this, ptr, TRUE);
8027 + /* redraw gdb console window when displayed */
8028 + gdb_redraw(this->buf);
8031 + gdb_lvl2_init(this);
8035 + err = "This |+gdb| version does not support level 2 mode";
8040 + fprintf(stderr, "`run' commands do input and output on the terminal %s\n", tty_name);
8044 + } while ((ptr = parse_note(this, ptr)) != NULL);
8046 + /* left shift buffer to last start of line */
8047 + if ((ptr = (char_u *)strrchr((char *)gdb_buf, (int)NL)) != NULL)
8049 + len = STRLEN(ptr + 1);
8050 + clewn_memmove(gdb_buf, ptr + 1, len);
8051 + last = (char_u *)gdb_buf + len;
8055 + # ifdef GDB_LVL2_SUPPORT
8056 + /* could not find the needle: hope for the best and fall back
8057 + * to annotation level 2 and send version again */
8058 + write(this->fd, SG_LVL_2, strlen(SG_LVL_2));
8059 + write(this->fd, SG_VERSION, strlen(SG_VERSION));
8061 + gdb_popup_console(this);
8064 + this->syntax = TRUE; /* force syntax highlite */
8065 + gdb_write_buf(this, (char_u *)SG_INTRO_2, TRUE);
8066 + this->syntax = FALSE;
8068 + gdb_lvl2_init(this);
8071 + err = "This |+gdb| version does not support level 2 mode";
8083 + # ifdef GDB_LVL3_SUPPORT
8084 + /* Print a value in a netbeans balloon */
8085 + # define PRINT_VALUE "^done,value=\""
8087 + gdb_print_value(this, state, line, obs)
8091 + struct obstack *obs;
8093 + # ifdef HAVE_CLEWN
8094 + char_u * res = NULL;
8101 + if (this->balloon_txt != NULL) {
8102 + obstack_strcat(obs, "server interpreter-exec mi \"-data-evaluate-expression ");
8103 + obstack_strcat(obs, this->balloon_txt);
8104 + obstack_strcat0(obs, "\"\n");
8106 + FREE(this->lvl3.result);
8107 + return (char_u *)obstack_finish(obs);
8112 + gdb_cat(&res, this->lvl3.result);
8113 + gdb_cat(&res, line);
8114 + xfree(this->lvl3.result);
8115 + this->lvl3.result = res;
8118 + case OOB_COMPLETE:
8119 + if (this->lvl3.result != NULL
8120 + && (ptr = STRSTR(this->lvl3.result, PRINT_VALUE)) != NULL
8121 + && (ptr += strlen(PRINT_VALUE))
8122 + && (quote = (char_u *)strrchr(ptr, '"')) != NULL)
8125 + obstack_strcat(obs, "\" ");
8126 + obstack_strcat(obs, this->balloon_txt);
8127 + obstack_strcat(obs, " = ");
8128 + obstack_strcat(obs, ptr);
8129 + obstack_strcat0(obs, " \"");
8131 + res = (char_u *)obstack_finish(obs);
8132 + gdb_showBalloon(res, obs);
8135 + FREE(this->balloon_txt);
8136 + FREE(this->lvl3.result);
8139 + # endif /* HAVE_CLEWN*/
8142 + # endif /* GDB_LVL3_SUPPORT */
8144 + /* Get instruction at $pc */
8146 + gdb_get_pc(this, state, line, obs)
8150 + struct obstack *obs;
8154 + if (obs) {} /* keep compiler happy */
8161 + if (this->state & GS_STOPPED)
8163 + this->state &= ~GS_STOPPED;
8164 + return "server x/i $pc\n";
8169 + if ((this->pc = gdb_regexec(line, PAT_ADD, 1, NULL)) != NULL)
8171 + /* Replace TAB with a space */
8172 + for (ptr = line; *ptr != NUL; ptr++)
8176 + gdb_status(this, line, obs);
8183 + /* Get frame info */
8185 + gdb_get_frame(this, state, line, obs)
8189 + struct obstack *obs;
8191 + char_u *res = NULL;
8193 + if (obs) {} /* keep compiler happy */
8198 + FREE(this->oob_result);
8199 + return "server frame\n";
8202 + gdb_cat(&res, this->oob_result);
8203 + gdb_cat(&res, line);
8204 + xfree(this->oob_result);
8205 + this->oob_result = res;
8208 + case OOB_COMPLETE:
8209 + xfree(this->frame_pc);
8210 + if (this->oob_result != NULL
8211 + && (this->frame_pc = gdb_regexec(this->oob_result, PAT_FRAME, 1, NULL)) != NULL) {
8212 + xfree(this->asm_add);
8213 + this->asm_add = (char_u *)clewn_strsave((char *)this->frame_pc);
8216 + if (this->pc != NULL) {
8217 + this->frame_pc = (char_u *)clewn_strsave((char *)this->pc);
8218 + xfree(this->asm_add);
8219 + this->asm_add = (char_u *)clewn_strsave((char *)this->frame_pc);
8223 + FREE(this->oob_result);
8229 + # ifdef GDB_LVL3_SUPPORT
8230 + /* Stack info frame */
8232 + gdb_info_frame(this, state, line, obs)
8236 + struct obstack *obs;
8238 + char_u *res = NULL;
8240 + if (obs) {} /* keep compiler happy */
8245 + FREE(this->lvl3.result);
8246 + return "server info frame\n";
8249 + gdb_cat(&res, this->lvl3.result);
8250 + gdb_cat(&res, line);
8251 + xfree(this->lvl3.result);
8252 + this->lvl3.result = res;
8255 + case OOB_COMPLETE:
8256 + this->frame_curlvl = -1;
8257 + if (this->lvl3.result != NULL
8258 + && (res = gdb_regexec(this->lvl3.result, PAT_INFO_FRAME, 1, NULL)) != NULL) {
8259 + this->frame_curlvl = atoi((char *)res);
8263 + FREE(this->lvl3.result);
8269 + # define SOURCE_FILENAME "\",file=\""
8270 + # define SOURCE_LINENUM "\",line=\""
8271 + /* Change frame highlight according to new frame level */
8273 + gdb_stack_frame(this, state, line, obs)
8277 + struct obstack *obs;
8279 + char_u * res = NULL;
8291 + /* get info about frame_curlvl:
8292 + * ^done,stack=[frame={level="1",addr="0x080483bb",func="main",file="cltest_main.c",line="12"}] */
8293 + if (this->frame_curlvl >= 0) {
8294 + FREE(this->lvl3.result);
8296 + sprintf(tmp, "%d %d", this->frame_curlvl, this->frame_curlvl);
8297 + obstack_strcat(obs, "server interpreter-exec mi \"-stack-list-frames ");
8298 + obstack_strcat(obs, tmp);
8299 + obstack_strcat0(obs, "\"\n");
8300 + return (char *)obstack_finish(obs);
8305 + gdb_cat(&res, this->lvl3.result);
8306 + gdb_cat(&res, line);
8307 + xfree(this->lvl3.result);
8308 + this->lvl3.result = res;
8311 + case OOB_COMPLETE:
8312 + if (this->lvl3.result != NULL
8313 + && (ptr = STRSTR(this->lvl3.result, SOURCE_FILENAME)) != NULL
8314 + && (pnum = STRSTR(this->lvl3.result, SOURCE_LINENUM)) != NULL)
8316 + pnum += strlen(SOURCE_FILENAME);
8317 + lnum = atoi((char *)pnum);
8319 + ptr += strlen(SOURCE_FILENAME);
8321 + if ((quote = STRCHR(ptr, '"')) != NULL) {
8322 + fname = (char_u *)obstack_copy0(obs, ptr, (quote - ptr));
8326 + /* set frame sign only if this is a new fname/lnum position */
8327 + if (this->frame_fname == NULL
8328 + || STRCMP(this->frame_fname, fname) != 0 || this->frame_lnum != lnum) {
8329 + FREE(this->frame_fname);
8330 + this->frame_fname = (char_u *)clewn_strsave((char *)fname);
8331 + this->frame_lnum = lnum;
8332 + rc = gdb_fr_set(this, fname, &lnum, obs);
8337 + if (rc != 0 && p_asm != 0)
8338 + this->pool.hilite = TRUE; /* do asm frame highliting */
8339 + FREE(this->lvl3.result);
8344 + # endif /* GDB_LVL3_SUPPORT */
8346 + /* Get symbol file name */
8348 + gdb_get_sfile(this, state, line, obs)
8352 + struct obstack *obs;
8354 + char_u *res = NULL;
8359 + return "server info target\n";
8362 + if (this->oob.cnt == 1
8363 + && (res = gdb_regexec(line, PAT_SFILE, 1, obs)) != NULL
8364 + && (this->sfile == NULL || STRCMP(res, this->sfile) != 0))
8366 + gdb_status(this, (char_u *)"new symbols", obs);
8367 + xfree(this->sfile);
8368 + this->sfile = (char_u *)clewn_strsave((char *)res);
8372 + case OOB_COMPLETE:
8373 + if (this->oob.cnt == 0)
8375 + gdb_status(this, (char_u *)"empty target", obs);
8376 + FREE(this->sfile);
8383 + /* Get GDB source directories */
8385 + gdb_get_sourcedir(this, state, line, obs)
8389 + struct obstack *obs;
8391 + char_u *res = NULL;
8393 + if (obs) {} /* keep compiler happy */
8398 + FREE(this->lvl3.result);
8399 + return "server show directories\n";
8402 + gdb_cat(&res, this->lvl3.result);
8403 + gdb_cat(&res, line);
8404 + xfree(this->lvl3.result);
8405 + this->lvl3.result = res;
8408 + case OOB_COMPLETE:
8409 + if (this->lvl3.result != NULL)
8411 + xfree(this->directories);
8412 + this->directories = gdb_regexec(this->lvl3.result, PAT_DIR, 1, NULL);
8413 + FREE(this->lvl3.result);
8420 + #ifdef GDB_LVL3_SUPPORT
8422 + /* Source the project file */
8424 + gdb_source_project(this, state, line, obs)
8428 + struct obstack *obs;
8433 + if (this->project_file != NULL
8435 + && this->project_state == PROJ_SOURCEIT)
8437 + this->project_state = PROJ_DONE;
8438 + fprintf(stderr, "source %s\n", this->project_file);
8440 + if (this->sfile != NULL)
8441 + fprintf(stderr, "Warning: symbol table \"%s\" was loaded before sourcing the project file\n", this->sfile);
8443 + obstack_strcat(obs, "server source ");
8444 + obstack_strcat(obs, this->project_file);
8445 + obstack_strcat0(obs, "\n");
8446 + return (char_u *)obstack_finish(obs);
8452 + fprintf(stderr, "%s\n", line);
8455 + case OOB_COMPLETE:
8456 + /* force getting the source file list from gdb */
8457 + this->lvl3.get_source_list = TRUE;
8459 + /* this is required after 'restart' to display the gdb prompt */
8460 + fprintf(stderr, this->prompt);
8467 + # define CWD_VALUE "^done,cwd=\""
8468 + /* Get current working directory */
8470 + gdb_get_pwd(this, state, line, obs)
8474 + struct obstack *obs;
8476 + char_u * res = NULL;
8480 + if (obs) {} /* keep compiler happy */
8485 + if (this->mode != GDB_MODE_LVL2) {
8486 + FREE(this->lvl3.result);
8487 + return "server interpreter-exec mi \"-environment-pwd\"\n";
8492 + gdb_cat(&res, this->lvl3.result);
8493 + gdb_cat(&res, line);
8494 + xfree(this->lvl3.result);
8495 + this->lvl3.result = res;
8498 + case OOB_COMPLETE:
8499 + if (this->lvl3.result != NULL
8500 + && (ptr = STRSTR(this->lvl3.result, CWD_VALUE)) != NULL
8501 + && (ptr += strlen(CWD_VALUE))
8502 + && (quote = (char_u *)strrchr(ptr, '"')) != NULL)
8505 + gdb_cat(&res, (char_u *)"cd ");
8506 + gdb_cat(&res, ptr);
8507 + gdb_cat(&res, (char_u *)"\n");
8512 + FREE(this->lvl3.result);
8518 + # define ARGS_VALUE "Argument list to give program being debugged when it is started is \""
8521 + gdb_get_args(this, state, line, obs)
8525 + struct obstack *obs;
8527 + char_u * res = NULL;
8531 + if (obs) {} /* keep compiler happy */
8536 + FREE(this->lvl3.result);
8537 + return "server show args\n";
8540 + gdb_cat(&res, this->lvl3.result);
8541 + gdb_cat(&res, line);
8542 + xfree(this->lvl3.result);
8543 + this->lvl3.result = res;
8546 + case OOB_COMPLETE:
8547 + if (this->lvl3.result != NULL
8548 + && (ptr = STRSTR(this->lvl3.result, ARGS_VALUE)) != NULL
8549 + && (ptr += strlen(ARGS_VALUE))
8550 + && (quote = (char_u *)strrchr(ptr, '"')) != NULL)
8553 + gdb_cat(&res, "set args ");
8554 + gdb_cat(&res, ptr);
8555 + gdb_cat(&res, "\n");
8556 + xfree(this->args);
8560 + FREE(this->lvl3.result);
8567 + /* Get GDB current source file */
8569 + gdb_source_cur(this, state, line, obs)
8573 + struct obstack *obs;
8575 + char_u *res = NULL;
8577 + if (obs) {} /* keep compiler happy */
8582 + FREE(this->lvl3.source_cur);
8583 + return "server interpreter-exec mi \"-file-list-exec-source-file\"\n";
8586 + gdb_cat(&res, this->lvl3.source_cur);
8587 + gdb_cat(&res, line);
8588 + xfree(this->lvl3.source_cur);
8589 + this->lvl3.source_cur = res;
8592 + case OOB_COMPLETE:
8598 + /* Get GDB current source file */
8600 + gdb_source_list(this, state, line, obs)
8604 + struct obstack *obs;
8606 + char_u *res = NULL;
8608 + if (obs) {} /* keep compiler happy */
8613 + if (this->lvl3.get_source_list || this->lvl3.source_list == NULL) {
8614 + FREE(this->lvl3.source_list);
8615 + this->lvl3.get_source_list = FALSE;
8616 + return "server interpreter-exec mi \"-file-list-exec-source-files\"\n";
8621 + gdb_cat(&res, this->lvl3.source_list);
8622 + gdb_cat(&res, line);
8623 + xfree(this->lvl3.source_list);
8624 + this->lvl3.source_list = res;
8627 + case OOB_COMPLETE:
8632 + #endif /* GDB_LVL3_SUPPORT */
8634 + # ifdef GDB_LVL3_SUPPORT
8635 + # define BKPT_RECORD "bkpt={number=\""
8636 + # define BKPT_ADDR "\",addr=\""
8638 + * When a breakpoint is being set and asm option is on, get the
8639 + * instruction address of the last breakpoint, the one being set.
8640 + * This address is used in get_asm() to disassemble the function
8641 + * containing this address.
8644 + get_lastbp(this, state, line, obs)
8648 + struct obstack *obs;
8650 + char_u *res = NULL;
8651 + int found = FALSE;
8652 + char_u *record = NULL;
8658 + if (obs) {} /* keep compiler happy */
8663 + /* GDB sends sometimes ANO_BP_INVALID when stepping, even
8664 + * though no breakpoints have been changed.
8665 + * Avoid checking for last bp in this case, because this
8666 + * may cause hiliting a bp in a new buffer when what is
8667 + * expected is a new frame */
8668 + if (this->bp_state & BPS_FR_INVALID)
8671 + /* A breakpoint is being set in assembly */
8672 + if (p_asm != 0 && (this->bp_state & BPS_INVALID)
8673 + && (this->bp_state & BPS_BP_SET))
8675 + this->bp_state &= ~BPS_BP_SET;
8676 + FREE(this->lvl3.result);
8678 + /* fetch GDB bp table info */
8679 + return "server interpreter-exec mi -break-list\n";
8684 + gdb_cat(&res, this->lvl3.result);
8685 + gdb_cat(&res, line);
8686 + xfree(this->lvl3.result);
8687 + this->lvl3.result = res;
8690 + case OOB_COMPLETE:
8691 + if ((ptr = this->lvl3.result) != NULL)
8693 + /* search for last record in breakpoint table */
8696 + if ((ptr = STRSTR(ptr, BKPT_RECORD)) != NULL)
8702 + while (ptr != NULL);
8705 + if (record != NULL
8706 + && (bp_num = atoi((char *)(record + strlen(BKPT_RECORD)))) > 0)
8708 + /* look it up in bpinfo list */
8709 + for (p = this->bpinfo; p != NULL; p = p->next)
8711 + if (bp_num == p->id)
8718 + /* not found: set asm_add so that get_asm will
8719 + * do the disassembling */
8720 + if (! found && (addr = STRSTR(record, BKPT_ADDR)) != NULL)
8722 + xfree(this->asm_add);
8724 + gdb_regexec(addr + strlen(BKPT_ADDR), PAT_ADD, 1, NULL);
8728 + FREE(this->lvl3.result);
8734 + # endif /* GDB_LVL3_SUPPORT */
8736 + /* Get the function name corresponding to asm_add */
8738 + gdb_get_asmfunc(this, state, line, obs)
8742 + struct obstack *obs;
8747 + if (this->asm_add != NULL)
8749 + obstack_strcat(obs, "server info symbol 0x");
8750 + obstack_strcat(obs, this->asm_add);
8751 + obstack_strcat0(obs, "\n");
8752 + return (char *)obstack_finish(obs);
8754 + FREE(this->asm_func);
8758 + xfree(this->asm_func);
8759 + this->asm_func = gdb_regexec(line, PAT_ASM_FUNC, 1, NULL);
8766 + * This function is a hack to fix errors occuring in GDB command
8767 + * "info symbol ADDR" that sometimes cannot find the symbol corresponding to
8768 + * a given ADDR, when GDB command "print/a ADDR" can.
8769 + * "print/a ADDR" is used as a last resort because it changes the value history.
8770 + * "output/a ADDR" does not change the value history, but the output of this
8771 + * command misses a newline.
8774 + gdb_get_asmfunc_hack(this, state, line, obs)
8778 + struct obstack *obs;
8783 + if (this->asm_add != NULL && this->asm_func == NULL)
8785 + obstack_strcat(obs, "server print/a 0x");
8786 + obstack_strcat(obs, this->asm_add);
8787 + obstack_strcat0(obs, "\n");
8788 + return (char *)obstack_finish(obs);
8793 + xfree(this->asm_func);
8794 + this->asm_func = gdb_regexec(line, PAT_ASM_FUNC_P, 1, NULL);
8800 + # define ASM_ABORTED "DISASSEMBLY ABORTED"
8803 + * Disassemble new function containing asm_add and highlight asm_add
8804 + * if this->pool.hilite is TRUE
8807 + gdb_get_asm(this, state, line, obs)
8811 + struct obstack *obs;
8814 + buf_T *buf = this->pool.buf[this->pool.idx];
8815 + buf_T *oldbuf = curbuf;
8816 + char_u *res = NULL;
8825 + FREE(this->asm_add);
8829 + lnum = (buf != NULL ? BUFLASTL(buf) : 0);
8834 + if (this->asm_add != NULL && !gdb_as_frset(this, obs))
8836 + /* pickup least recent buffer */
8837 + for (i = this->pool.max; i > 0; )
8840 + if (this->pool.age[i] >= age && this->pool.buf[i] != NULL)
8842 + age = this->pool.age[i];
8847 + /* no buffers in pool */
8848 + if ((buf = this->pool.buf[oldest]) == NULL)
8850 + this->pool.hilite = FALSE;
8851 + FREE(this->asm_add);
8854 + this->pool.idx = oldest;
8856 + /* clear the buffer */
8857 + gdb_clear_asmbuf(this, buf);
8859 + /* init msg_busy */
8860 + obstack_strcat(obs, "Disassembling 0x");
8861 + obstack_strcat0(obs, this->asm_add);
8862 + res = (char_u *)obstack_finish(obs);
8863 + gdb_msg_busy(res);
8866 + obstack_strcat(obs, "server disassemble 0x");
8867 + obstack_strcat(obs, this->asm_add);
8868 + obstack_strcat0(obs, "\n");
8869 + return (char *)obstack_finish(obs);
8871 + this->pool.hilite = FALSE;
8879 + /* concatenate with line after an annotation
8880 + * and replace line, otherwise add */
8881 + if (this->line != NULL && this->annoted)
8883 + obstack_strcat(obs, this->line);
8884 + obstack_strcat0(obs, line);
8885 + line = (char_u *)obstack_finish(obs);
8886 + ml_delete(lnum--, FALSE);
8889 + /* first line: remove empty line after the inserted one */
8890 + if (ml_append(lnum, line, 0, 0) == OK && lnum == 0)
8891 + ml_delete(buf->b_ml.ml_line_count, FALSE);
8894 + if ((this->oob.cnt % 1000) == 0)
8895 + gdb_msg_busy(NULL);
8897 + xfree(this->line);
8898 + this->line = (char_u *)clewn_strsave((char *)line);
8901 + case OOB_COMPLETE:
8906 + if (this->oob.state & OS_INTR)
8908 + if (lnum >= 1 && STRCMP(ASM_ABORTED, ml_get(1)) != 0)
8910 + /* Clear buffer when interrupted */
8911 + while (lnum-- > 0)
8912 + ml_delete(buf->b_ml.ml_line_count, FALSE);
8914 + ml_append(0, (char_u *)ASM_ABORTED, 0, 0);
8915 + lnum = buf->b_ml.ml_line_count;
8916 + changed_lines(1, 0, lnum, lnum);
8919 + this->pool.age[this->pool.idx] = ASM_OLD;
8920 + gdb_edit_file(this, buf, NULL, 1, obs);
8923 + /* write the prompt */
8924 + gdb_write_buf(this, this->line, TRUE);
8929 + changed_lines(1, 0, lnum, lnum);
8931 + /* set buffer name to function name */
8932 + if (this->asm_func != NULL)
8934 + obstack_strcat(obs, this->asm_func);
8935 + obstack_strcat0(obs, "-asm");
8936 + res = (char_u *)obstack_finish(obs);
8937 + gdb_as_setname(res);
8941 + /* highlite $asm_add and update window if displayed */
8942 + if (! gdb_as_frset(this, obs) && (win = gdb_btowin(buf)) != NULL)
8944 + gdb_set_cursor(win, 1);
8945 + redraw_win_later(win, NOT_VALID);
8949 + msg_clr_cmdline();
8950 + FREE(this->asm_add);
8951 + this->pool.hilite = FALSE;
8958 + char_u *res = NULL;
8963 + FREE(this->asm_add);
8970 + if (this->asm_add != NULL && ! gdb_as_frset(this, obs))
8972 + FREE(this->pool.name);
8974 + /* get a unique file name for this disassembled function
8975 + * and open the file for creation
8976 + * the file name suffix is '.clasm' so that it can be set
8977 + * to 'autoread' by the runtime file clewn.vim */
8978 + if (this->asm_func != NULL) {
8979 + obstack_strcat(obs, this->asm_func);
8980 + obstack_strcat0(obs, ".clasm");
8981 + fname = (char_u *)obstack_finish(obs);
8983 + if (this->asm_func == NULL || (this->pool.fd = clewn_opentmpfile(fname,
8984 + &(this->pool.name), 1)) == NULL)
8986 + this->pool.hilite = FALSE;
8989 + this->pool.line_offset = 0L;
8991 + /* create the buffer */
8992 + if ((this->pool.buf = cnb_create_buf(this->pool.name)) == -1)
8994 + this->pool.hilite = FALSE;
8996 + fclose(this->pool.fd);
8997 + this->pool.fd = NULL;
8998 + if (this->pool.name != NULL)
8999 + (void)unlink(this->pool.name);
9000 + FREE(this->pool.name);
9004 + /* init msg_busy */
9005 + obstack_strcat(obs, "Disassembling 0x");
9006 + obstack_strcat0(obs, this->asm_add);
9007 + res = (char_u *)obstack_finish(obs);
9008 + gdb_msg_busy(res);
9011 + this->lastline = 0;
9012 + obstack_strcat(obs, "server disassemble 0x");
9013 + obstack_strcat(obs, this->asm_add);
9014 + obstack_strcat0(obs, "\n");
9015 + return (char_u *)obstack_finish(obs);
9017 + this->pool.hilite = FALSE;
9021 + if (this->pool.fd == NULL)
9024 + /* ignore when interrupted */
9025 + if (this->oob.state & OS_INTR)
9028 + /* concatenate with line after an annotation
9029 + * and replace line, otherwise add */
9030 + if (this->line != NULL && this->annoted)
9032 + obstack_strcat(obs, this->line);
9033 + obstack_strcat0(obs, line);
9034 + line = (char_u *)obstack_finish(obs);
9037 + if (fseek(this->pool.fd, this->pool.line_offset, SEEK_SET) != 0)
9041 + /* write a newline except at first line */
9042 + if (this->lastline != 0)
9044 + if ((this->pool.line_offset = ftell(this->pool.fd)) == -1
9045 + || fputs("\n", this->pool.fd) < 0)
9050 + /* write the line */
9051 + if (fputs(line, this->pool.fd) < 0)
9054 + if ((this->oob.cnt % 400) == 0)
9055 + gdb_msg_busy(NULL);
9057 + xfree(this->line);
9058 + this->line = (char_u *)clewn_strsave((char *)line);
9061 + case OOB_COMPLETE:
9062 + if (this->pool.fd == NULL)
9065 + if (this->oob.state & OS_INTR)
9067 + FREE(this->asm_add);
9068 + this->pool.hilite = FALSE;
9073 + /* highlite $asm_add */
9074 + (void)gdb_as_frset(this, obs);
9076 + /* write last new line */
9077 + if (fputs("\n", this->pool.fd) < 0)
9080 + /* clear the line */
9081 + gdb_msg_busy("FIN");
9083 + /* set the buffer as an asm buffer */
9084 + cnb_set_asm(this->pool.buf);
9087 + FREE(this->asm_add);
9089 + this->pool.buf = -1;
9090 + fclose(this->pool.fd);
9091 + this->pool.fd = NULL;
9092 + FREE(this->pool.name);
9093 + this->pool.hilite = FALSE;
9098 + /* clear the line */
9099 + gdb_msg_busy("FIN");
9101 + cnb_kill(this->pool.buf);
9102 + this->pool.buf = -1;
9104 + if (this->pool.fd != NULL)
9105 + fclose(this->pool.fd);
9106 + this->pool.fd = NULL;
9108 + if (this->pool.name != NULL)
9109 + (void)unlink(this->pool.name);
9110 + FREE(this->pool.name);
9113 + # endif /* FEAT_GDB */
9115 + # ifdef GDB_LVL3_SUPPORT
9117 + * Get the breakpoints info record table.
9120 + get_bp(this, state, line, obs)
9124 + struct obstack *obs;
9126 + char_u *res = NULL;
9127 + char_u *record = NULL;
9134 + /* gdb 6.4 does not provide anymore the right annotations for breakpoints
9135 + * when in level 3 (note that they are still there when setting annotate
9136 + * level 2, I thought level 2 was deprecated, what a zoo !), so we look
9137 + * for new or changed breakpoints systematically now */
9138 + if (this->mode == GDB_MODE_LVL3)
9139 + this->bp_state = BPS_INVALID;
9141 + /* When an ANO_BP_INVALID annotation has been received,
9142 + * or when we are stepping (more accurately: got a new frame):
9143 + * fetch bp table */
9144 + if (this->bp_state & BPS_INVALID || this->bp_state & BPS_FR_INVALID)
9146 + FREE(this->lvl3.result);
9147 + this->bufIsChanged = FALSE;
9149 + /* handle case where an error occured last time */
9150 + FREE(this->record);
9151 + gdb_free_bplist(&(this->tmplist));
9153 + /* fetch GDB bp table info */
9154 + return "server interpreter-exec mi -break-list\n";
9157 + this->bp_state &= ~BPS_INVALID;
9158 + this->bp_state &= ~BPS_FR_INVALID;
9159 + this->bp_state &= ~BPS_BP_HIT;
9163 + gdb_cat(&res, this->lvl3.result);
9164 + gdb_cat(&res, line);
9165 + xfree(this->lvl3.result);
9166 + this->lvl3.result = res;
9169 + case OOB_COMPLETE:
9170 + if ((ptr = this->lvl3.result) != NULL)
9172 + /* process all records except last */
9175 + if ((ptr = STRSTR(ptr, BKPT_RECORD)) != NULL
9176 + && ptr > this->lvl3.result)
9179 + if (record != NULL)
9180 + process_record(this, record, obs);
9186 + while (ptr != NULL);
9188 + /* process last record */
9189 + if (record != NULL)
9190 + process_record(this, record, obs);
9192 + FREE(this->record);
9194 + /* All records left in the old table are breakpoints that have
9195 + * been deleted: delete the corresponding highliting sign */
9196 + for (p = this->bpinfo; p != NULL; p = p->next)
9197 + gdb_unlite(BP_SIGN_ID(p->id));
9199 + this->bp_state &= ~BPS_INVALID;
9200 + this->bp_state &= ~BPS_FR_INVALID;
9201 + this->bp_state &= ~BPS_BP_HIT;
9203 + /* replace with new table */
9204 + gdb_free_bplist(&(this->bpinfo));
9205 + this->bpinfo = this->tmplist;
9206 + this->tmplist = NULL;
9208 + FREE(this->lvl3.result);
9215 + # define BKPT_ENABLED "\",enabled=\""
9216 + # define BKPT_DISP "\",disp=\""
9217 + # define BKPT_SCRIPT "\",script={"
9218 + # define BKPT_TYPE "\",type=\"breakpoint\""
9219 + # define BKPT_LINE "\",line=\""
9220 + # define BKPT_SOURCE "\",file=\""
9221 + # define BKPT_AT "\",at=\"<"
9222 + /* Process the current info record */
9224 + process_record(this, record, obs)
9227 + struct obstack *obs;
9229 + char_u *bp_add = NULL;
9230 + char_u *bp_line = NULL;
9231 + char_u *bp_source = NULL;
9232 + char_u *bp_at = NULL;
9238 + /* allocate a new record or reuse an existing one
9239 + * and initialize its fields */
9240 + if (this->record == NULL)
9241 + this->record = (bpinfo_T *)xcalloc(sizeof(bpinfo_T));
9243 + this->record->id = -1;
9244 + this->record->enabled = TRUE;
9245 + # ifdef BP_INVALID_ANO_MISSING
9246 + this->record->disposition = TRUE;
9248 + this->record->cont = FALSE;
9250 + this->record->buf = NULL;
9252 + this->record->buf = -1;
9253 + this->record->typenr_en = -1;
9254 + this->record->typenr_dis = -1;
9256 + this->record->lnum = 0;
9257 + this->record->next = NULL;
9259 + /* breakpoint number */
9260 + this->record->id = atoi((char *)(record + strlen(BKPT_RECORD)));
9262 + /* enabled state */
9263 + if ((ptr = STRSTR(record, BKPT_ENABLED)) != NULL
9264 + && *(ptr + strlen(BKPT_ENABLED)) == 'n')
9265 + this->record->enabled = FALSE;
9267 + # ifdef BP_INVALID_ANO_MISSING
9269 + if ((ptr = STRSTR(record, BKPT_DISP)) != NULL
9270 + && STRSTR(ptr + strlen(BKPT_DISP), "keep") == NULL)
9271 + this->record->disposition = FALSE;
9274 + /* parse script for 'continue' as last statement */
9275 + if ((ptr = STRSTR(record, BKPT_SCRIPT)) != NULL)
9277 + ptr += strlen(BKPT_SCRIPT);
9278 + if ((end = STRCHR(ptr, '}')) != NULL)
9280 + while ((ptr = STRCHR(ptr, '"')) != NULL && ptr < end)
9283 + if (gdb_regexec(ptr, PAT_BP_CONT, 1, obs) != NULL
9284 + || gdb_regexec(ptr, PAT_BP_CONT, 2, obs) != NULL)
9286 + this->record->cont = TRUE; /* continue */
9293 + /* sanity check and discard watchpoints and others */
9294 + if (this->record->id <= 0 || STRSTR(record, BKPT_TYPE) == NULL)
9298 + if ((ptr = STRSTR(record, BKPT_ADDR)) != NULL)
9299 + bp_add = gdb_regexec(ptr + strlen(BKPT_ADDR), PAT_ADD, 1, obs);
9302 + if ((ptr = STRSTR(record, BKPT_LINE)) != NULL)
9304 + ptr += strlen(BKPT_LINE);
9305 + if ((quote = STRCHR(ptr, '"')) != NULL)
9306 + bp_line = (char_u *)obstack_copy0(obs, ptr, (quote - ptr));
9310 + if ((ptr = STRSTR(record, BKPT_SOURCE)) != NULL)
9312 + ptr += strlen(BKPT_SOURCE);
9313 + if ((quote = STRCHR(ptr, '"')) != NULL)
9314 + bp_source = (char_u *)obstack_copy0(obs, ptr, (quote - ptr));
9318 + if ((ptr = STRSTR(record, BKPT_AT)) != NULL)
9320 + ptr += strlen(BKPT_AT);
9321 + if ((quote = STRCHR(ptr, '>')) != NULL)
9323 + if ((plus = STRCHR(ptr, '+')) != NULL && plus < quote)
9324 + bp_at = (char_u *)obstack_copy0(obs, ptr, (plus - ptr));
9326 + bp_at = (char_u *)obstack_copy0(obs, ptr, (quote - ptr));
9330 + gdb_process_record(this, bp_add, bp_at, bp_line, bp_source, obs);
9333 + /* Update the variables objects and the variables window */
9335 + varobj_update(this, state, line, obs)
9339 + struct obstack *obs;
9344 + static char *result = NULL; /* mark the start and end of object operations */
9346 + char_u *res = NULL;
9352 + if (this->lvl3.varitem == NULL)
9354 + /* start with first in list */
9355 + this->lvl3.varitem = this->lvl3.varlist;
9356 + this->lvl3.varnext_cmd = VCMD_INIT;
9359 + /* next OOB_CMD */
9360 + if ((obj = this->lvl3.varitem) != NULL)
9362 + FREE(this->lvl3.result);
9364 + /* create a new object and give it a name */
9365 + if (this->lvl3.varnext_cmd == VCMD_INIT && obj->name == NULL)
9369 + this->var_buf != NULL
9375 + if (obj->format != NULL)
9376 + this->lvl3.varnext_cmd = VCMD_FORMAT;
9378 + this->lvl3.varnext_cmd = VCMD_PRINT;
9380 + this->lvl3.varcmd = VCMD_CREATE;
9382 + obstack_strcat(obs, "server interpreter-exec mi \"-var-create - * (");
9383 + obstack_strcat(obs, obj->expression);
9384 + obstack_strcat0(obs, ")\"\n");
9385 + return (char *)obstack_finish(obs);
9389 + /* remove silently from list */
9390 + remove_object(this, obj);
9395 + /* sanity check: an object must have a name
9396 + * this should never occur */
9397 + if (obj->name == NULL)
9399 + /* silently ignore this error */
9400 + this->lvl3.varnext_cmd = VCMD_INIT;
9401 + this->lvl3.varitem = obj->next;
9405 + /* search for the object in the variables window
9406 + * if it does not exist, then -var-delete it */
9407 + if (this->lvl3.varnext_cmd == VCMD_INIT)
9415 + obstack_strcat(obs, "^\\s*");
9416 + obstack_strcat(obs, obj->name);
9417 + obstack_strcat0(obs, ":");
9418 + ptrn = (char_u *)obstack_finish(obs);
9420 + if (this->var_buf == NULL
9421 + || (this->var_buf->b_ml.ml_flags & ML_EMPTY)
9422 + || (searchit(NULL, this->var_buf, &pos,
9423 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) == FAIL))
9427 + if (this->var_buf <= 0 || cnb_search_obj(obj->name, &lnum) == NULL)
9430 + /* not in gdb variables window, delete it */
9431 + this->lvl3.varcmd = VCMD_DELETE;
9433 + obstack_strcat(obs, "server interpreter-exec mi \"-var-delete var");
9434 + obstack_strcat(obs, obj->name);
9435 + obstack_strcat0(obs, "\"\n");
9436 + return (char *)obstack_finish(obs);
9440 + /* list children if any (need to run this cmd before update) */
9441 + if (this->lvl3.varnext_cmd == VCMD_INIT)
9443 + this->lvl3.varnext_cmd = VCMD_UPDATE;
9445 + if (obj->children)
9447 + this->lvl3.varcmd = VCMD_CHILDREN;
9449 + obstack_strcat(obs, "server interpreter-exec mi \"-var-list-children var");
9450 + obstack_strcat(obs, obj->name);
9451 + obstack_strcat0(obs, "\"\n");
9452 + return (char *)obstack_finish(obs);
9456 + /* set the format */
9457 + if (this->lvl3.varnext_cmd == VCMD_FORMAT)
9459 + if (obj->format != NULL && STRLEN(obj->format) == 2)
9461 + obstack_strcat(obs, "server interpreter-exec mi \"-var-set-format var");
9462 + obstack_strcat(obs, obj->name);
9464 + switch(*(obj->format + 1))
9467 + obstack_strcat0(obs, " binary\"\n");
9470 + obstack_strcat0(obs, " decimal\"\n");
9473 + obstack_strcat0(obs, " hexadecimal\"\n");
9476 + obstack_strcat0(obs, " octal\"\n");
9479 + obstack_strcat0(obs, " natural\"\n");
9483 + this->lvl3.varnext_cmd = VCMD_PRINT;
9484 + this->lvl3.varcmd = VCMD_FORMAT;
9486 + return (char *)obstack_finish(obs);
9490 + this->lvl3.varnext_cmd = VCMD_INIT;
9491 + this->lvl3.varitem = obj->next;
9496 + /* update object */
9497 + if (this->lvl3.varnext_cmd == VCMD_UPDATE)
9499 + this->lvl3.varnext_cmd = VCMD_PRINT;
9500 + this->lvl3.varcmd = VCMD_UPDATE;
9502 + obstack_strcat(obs, "server interpreter-exec mi \"-var-update var");
9503 + obstack_strcat(obs, obj->name);
9504 + obstack_strcat0(obs, "\"\n");
9505 + return (char *)obstack_finish(obs);
9509 + if (this->lvl3.varnext_cmd == VCMD_PRINT)
9511 + obj->state &= ~VS_ERROR;
9512 + this->lvl3.varcmd = VCMD_PRINT;
9514 + obstack_strcat(obs, "server output ");
9515 + obstack_strcat(obs, obj->format);
9516 + obstack_strcat(obs, " ");
9517 + obstack_strcat(obs, obj->expression);
9518 + obstack_strcat0(obs, "\n");
9519 + return (char *)obstack_finish(obs);
9522 + /* evaluate object expression */
9523 + if (this->lvl3.varnext_cmd == VCMD_EVALUATE)
9525 + this->lvl3.varcmd = VCMD_EVALUATE;
9527 + obstack_strcat(obs, "server interpreter-exec mi \"-var-evaluate-expression var");
9528 + obstack_strcat(obs, obj->name);
9529 + obstack_strcat0(obs, "\"\n");
9530 + return (char *)obstack_finish(obs);
9536 + gdb_cat(&res, this->lvl3.result);
9537 + gdb_cat(&res, line);
9538 + xfree(this->lvl3.result);
9539 + this->lvl3.result = res;
9542 + case OOB_COMPLETE:
9544 + return varobj_complete(this, obs);
9546 + /* start of object operations */
9547 + if (result == NULL && this->var_buf > 0)
9548 + cnb_startAtomic(this->var_buf);
9550 + result = varobj_complete(this, obs);
9552 + /* end of object operations */
9553 + if (result == NULL && this->var_buf > 0)
9554 + cnb_endAtomic(this->var_buf);
9563 + # define VOBJ_NAME "^done,name=\"var"
9564 + # define VOBJ_CHILD "\",numchild=\""
9565 + # define VOBJ_SCOPE "\",in_scope=\""
9566 + # define VOBJ_VALUE "^done,value=\""
9568 + * Process the OOB_COMPLETE part of varobj_update()
9569 + * Return anything not NULL except when last object in varlist
9570 + * and after the last varcmd which may be: a failed VCMD_CREATE,
9571 + * VCMD_DELETE, highlighted VCMD_UPDATE, VCMD_PRINT, VCMD_EVALUATE
9574 + varobj_complete(this, obs)
9576 + struct obstack *obs;
9578 + char_u *displine; /* the new display item line */
9581 + buf_T *oldbuf = curbuf;
9591 + if ((obj = this->lvl3.varitem) != NULL)
9593 + switch (this->lvl3.varcmd)
9596 + /* result of object creation */
9597 + if (this->lvl3.result != NULL
9598 + && (ptr = STRSTR(this->lvl3.result, VOBJ_NAME)) != NULL
9599 + && (ptr += strlen(VOBJ_NAME))
9600 + && (quote = STRCHR(ptr, '"')) != NULL
9601 + && (child = STRSTR(this->lvl3.result, VOBJ_CHILD)) != NULL)
9603 + obj->name = (char_u *)clewn_strnsave((char *)ptr, (quote - ptr));
9604 + obj->children = (atoi((char *)(child + strlen(VOBJ_CHILD))) > 0);
9606 + FREE(this->lvl3.result);
9607 + return (char *)obj; /* next command */
9611 + EMSG(_("Unable to create variable object"));
9612 + remove_object(this, obj);
9613 + FREE(this->lvl3.result);
9614 + this->lvl3.varnext_cmd = VCMD_INIT;
9615 + return (char *)this->lvl3.varitem; /* next object */
9620 + remove_object(this, obj);
9621 + FREE(this->lvl3.result);
9622 + this->lvl3.varnext_cmd = VCMD_INIT;
9623 + return (char *)this->lvl3.varitem; /* next object */
9625 + case VCMD_CHILDREN:
9626 + FREE(this->lvl3.result);
9627 + return (char *)obj; /* next command */
9630 + FREE(this->lvl3.result);
9631 + return (char *)obj; /* next command */
9634 + if (this->lvl3.result != NULL
9635 + &&(ptr = STRSTR(this->lvl3.result, VOBJ_SCOPE)) != NULL)
9637 + ptr += strlen(VOBJ_SCOPE);
9638 + if ((STRSTR(ptr, "false")) == ptr)
9640 + /* set "out of scope" highlighting (={-}) */
9641 + varobj_hilite(this, obj, (int)'-', obs);
9646 + /* object needs updating */
9647 + FREE(this->lvl3.result);
9648 + return (char *)obj; /* next command */
9653 + /* turn off highlighting */
9654 + varobj_hilite(this, obj, (int)'=', obs);
9660 + /* fall back to GDB/MI when unable to print expression
9661 + * because it's not the right frame */
9662 + if (obj->state & VS_ERROR)
9664 + obj->state &= ~VS_ERROR;
9665 + this->lvl3.varnext_cmd = VCMD_EVALUATE;
9666 + FREE(this->lvl3.result);
9667 + return (char *)obj; /* next command */
9670 + /* build the display line including ={*}, the hiliting sign */
9671 + obstack_strcat(obs, obj->name);
9672 + obstack_strcat(obs, ":");
9673 + obstack_strcat(obs, obj->format);
9674 + obstack_strcat(obs, " ");
9675 + obstack_strcat(obs, obj->expression);
9676 + obstack_strcat(obs, " ={*} ");
9677 + if (this->lvl3.result != NULL) {
9678 + obstack_strcat0(obs, this->lvl3.result);
9680 + displine = (char_u *)obstack_finish(obs);
9682 + /* add the newly created object to variables window */
9683 + if (obj->state & VS_INIT)
9686 + if (this->var_buf != NULL)
9688 + lnum = BUFLASTL(this->var_buf);
9690 + /* edit variables buffer in available window */
9691 + if (gdb_edit_file(this, this->var_buf, NULL, lnum, obs) != NULL)
9693 + /* add to variables buffer */
9694 + if (ml_append(lnum, displine, 0, 0) == OK)
9696 + /* first line ever: remove empty line after the
9697 + * one just inserted */
9699 + ml_delete(this->var_buf->b_ml.ml_line_count, FALSE);
9701 + changed_lines(this->var_buf->b_ml.ml_line_count - 1,
9702 + 0, this->var_buf->b_ml.ml_line_count, 1);
9705 + /* update top line */
9706 + curwin->w_cursor.lnum = this->var_buf->b_ml.ml_line_count;
9709 + /* status line changed */
9710 + curwin->w_redr_status = TRUE;
9712 + /* move back to previous window if still there */
9713 + if ((win = gdb_btowin(oldbuf)) != NULL)
9716 + obj->state &= ~VS_INIT;
9719 + if (this->var_buf > 0)
9721 + cnb_append(this->var_buf, displine, obs);
9722 + obj->state &= ~VS_INIT;
9727 + /* update and highlight object value */
9729 + varobj_replace(this, obj, displine, obs);
9733 + case VCMD_EVALUATE:
9734 + if (this->lvl3.result != NULL
9735 + && (ptr = STRSTR(this->lvl3.result, VOBJ_VALUE)) != NULL
9736 + && (ptr += strlen(VOBJ_VALUE))
9737 + && (quote = (char_u *)strrchr((char *)ptr, '"')) != NULL)
9739 + res = (char_u *)obstack_copy0(obs, ptr, (quote - ptr));
9741 + /* remove all `\' in `\"' */
9742 + for (ptr = last = res; *ptr; ptr++)
9744 + if (*ptr != '\\' || *(ptr + 1) != '"')
9749 + /* build the display line including ={*}, the hiliting sign */
9750 + obstack_strcat(obs, obj->name);
9751 + obstack_strcat(obs, ":");
9752 + obstack_strcat(obs, obj->format);
9753 + obstack_strcat(obs, " ");
9754 + obstack_strcat(obs, obj->expression);
9755 + obstack_strcat(obs, " ={*} ");
9756 + obstack_strcat0(obs, res);
9757 + displine = (char_u *)obstack_finish(obs);
9760 + /* update and highlight object value */
9761 + varobj_replace(this, obj, displine, obs);
9770 + FREE(this->lvl3.result);
9771 + this->lvl3.varitem = obj->next;
9772 + this->lvl3.varnext_cmd = VCMD_INIT;
9774 + /* When not at the end of varlist, return a non null object
9775 + * to get gdb_oob_send() to call again varobj_update() for
9776 + * the next object */
9777 + return (char *)this->lvl3.varitem;
9780 + # define OBHI_CHANGED " ={*} "
9781 + # define OBHI_UNCHANGED " ={=} "
9782 + # define OBHI_DESCOPED " ={-} "
9783 + /* Change object highlighting to type */
9785 + varobj_hilite(this, obj, type, obs)
9788 + int type; /* hiliting type, may be '*', '=' or '-' */
9789 + struct obstack *obs;
9792 + buf_T *oldbuf = curbuf;
9803 + /* search for obj in variables window */
9804 + obstack_strcat(obs, "^\\s*");
9805 + obstack_strcat(obs, obj->name);
9806 + obstack_strcat0(obs, ":");
9807 + ptrn = (char_u *)obstack_finish(obs);
9809 + if (this->var_buf != NULL && obj != NULL && obj->name != NULL
9810 + && ! (this->var_buf->b_ml.ml_flags & ML_EMPTY)
9811 + && searchit(NULL, this->var_buf, &pos,
9812 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
9814 + line = ml_get_buf(this->var_buf, pos.lnum, FALSE);
9815 + oldline = obstack_strsave(obs, line);
9817 + if ((type == '-' && ((ptr = STRSTR(oldline, OBHI_CHANGED)) != NULL
9818 + || (ptr = STRSTR(oldline, OBHI_UNCHANGED)) != NULL))
9819 + || (type == '*' && ((ptr = STRSTR(oldline, OBHI_UNCHANGED)) != NULL
9820 + || (ptr = STRSTR(oldline, OBHI_DESCOPED)) != NULL))
9821 + || (type == '=' && ((ptr = STRSTR(oldline, OBHI_DESCOPED)) != NULL
9822 + || (ptr = STRSTR(oldline, OBHI_CHANGED)) != NULL)))
9824 + *(ptr + 3) = type;
9826 + /* replace line */
9827 + curbuf = this->var_buf;
9828 + ml_replace(pos.lnum, oldline, TRUE);
9829 + changed_lines(pos.lnum, 0, pos.lnum + 1, 0);
9832 + if ((win = gdb_btowin(this->var_buf)) != NULL)
9833 + redraw_win_later(win, NOT_VALID);
9844 + /* search for obj in variables buffer */
9845 + if (this->var_buf > 0 && obj != NULL && obj->name != NULL
9846 + && (oldline = cnb_search_obj(obj->name, &lnum)) != NULL)
9848 + line = obstack_strsave(obs, oldline);
9850 + if ((type == '-' && ((ptr = STRSTR(line, OBHI_CHANGED)) != NULL
9851 + || (ptr = STRSTR(line, OBHI_UNCHANGED)) != NULL))
9852 + || (type == '*' && ((ptr = STRSTR(line, OBHI_UNCHANGED)) != NULL
9853 + || (ptr = STRSTR(line, OBHI_DESCOPED)) != NULL))
9854 + || (type == '=' && ((ptr = STRSTR(line, OBHI_DESCOPED)) != NULL
9855 + || (ptr = STRSTR(line, OBHI_CHANGED)) != NULL)))
9857 + *(ptr + 3) = type;
9859 + /* replace line */
9860 + cnb_replace(this->var_buf, line, lnum, obs);
9866 + /* Replace object line in variables buffer with line */
9868 + varobj_replace(this, obj, line, obs)
9872 + struct obstack *obs;
9875 + buf_T *oldbuf = curbuf;
9876 + win_T *oldwin = curwin;
9885 + /* search for object in variables window */
9886 + obstack_strcat(obs, "^\\s*");
9887 + obstack_strcat(obs, obj->name);
9888 + obstack_strcat0(obs, ":");
9889 + ptrn = (char_u *)obstack_finish(obs);
9891 + if (this->var_buf != NULL && obj != NULL && obj->name != NULL
9892 + && ! (this->var_buf->b_ml.ml_flags & ML_EMPTY)
9893 + && searchit(NULL, this->var_buf, &pos,
9894 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
9898 + /* replace line */
9899 + curbuf = this->var_buf;
9900 + ml_replace(lnum, line, TRUE);
9901 + changed_lines(lnum, 0, lnum + 1, 0);
9903 + if ((win = gdb_btowin(this->var_buf)) != NULL)
9905 + win->w_cursor.lnum = lnum;
9912 + win->w_redr_status = TRUE;
9914 + redraw_win_later(win, NOT_VALID);
9923 + /* search for object in variables buffer */
9924 + if (this->var_buf > 0 && obj != NULL && obj->name != NULL
9925 + && cnb_search_obj(obj->name, &lnum) != NULL)
9926 + cnb_replace(this->var_buf, line, lnum, obs);
9930 + /* Remove varobj item from valist */
9932 + remove_object(this, item)
9939 + for (pt = &(this->lvl3.varlist); *pt != NULL; pt = &((*pt)->next))
9942 + next = (*pt)->next;
9943 + this->lvl3.varitem = next;
9945 + xfree(item->name);
9946 + xfree(item->format);
9947 + xfree(item->expression);
9953 + # endif /* GDB_LVL3_SUPPORT */
9956 + * Add a breakpoint record to the head of the tmp list and highlite
9957 + * the corresponding sign if the record refers to a loaded buffer
9958 + * or to an editable file, and in this case load it.
9961 + gdb_process_record(this, address, at, line, source, obs)
9963 + char_u *address; /* breakpoint address */
9964 + char_u *at; /* breakpoint function */
9965 + char_u *line; /* breakpoint line in source */
9966 + char_u *source; /* breakpoint source file name */
9967 + struct obstack *obs;
9970 + win_T *oldwin = curwin;
9971 + bpinfo_T *record = this->record;
9972 + char_u *bp_file = NULL;
9973 + buf_T *buf = NULL;
9975 + bpinfo_T *p, **pt;
9981 + * Look for this breakpoint in previous list
9983 + for (pt = &(this->bpinfo); *pt != NULL; pt = &((*pt)->next))
9987 + /* The breakpoint number exists in the old table:
9988 + * update the highliting sign and do not even parse
9989 + * the line (assume the file and line of a breakpoint
9991 + * move the old record to tmplist and update its sign
9993 + if (record->id == p->id)
9995 + /* update enabled */
9996 + if (record->enabled != p->enabled)
9998 + p->enabled = record->enabled;
9999 + if ((p->typenr = gdb_define_sign(p->id, p->enabled)) != -1)
10001 + buf_addsign(p->buf, BP_SIGN_ID(p->id), p->lnum, p->typenr);
10002 + update_debug_sign(p->buf, p->lnum);
10006 + # ifdef BP_INVALID_ANO_MISSING
10007 + /* update disposition */
10008 + p->disposition = record->disposition;
10011 + /* update 'continue' */
10012 + p->cont = record->cont;
10014 + /* move from old list to new list */
10015 + *pt = p->next; /* unlink from old list */
10016 + p->next = this->tmplist; /* link to head of new table */
10017 + this->tmplist = p;
10018 + return; /* record may be reused */
10023 + * A new breakpoint number: edit the file if possible
10025 + /* An asm breakpoint */
10026 + if (address != NULL && at != NULL)
10028 + bp_file = obstack_strsave(obs, at);
10030 + /* Search all buffers in the asm buffer pool whose name starts
10031 + * with bp_file and find the one containing a line starting
10032 + * with address */
10033 + obstack_strcat(obs, "^\\s*0x0*");
10034 + obstack_strcat0(obs, address);
10035 + ptrn = (char_u *)obstack_finish(obs);
10037 + for (i = 0; i < this->pool.max; i++)
10042 + if (this->pool.buf[i] != NULL
10043 + && STRSTR(this->pool.buf[i]->b_fname, bp_file) != NULL
10044 + && !(this->pool.buf[i]->b_ml.ml_flags & ML_EMPTY)
10045 + && searchit(NULL, this->pool.buf[i], &pos,
10046 + FORWARD, ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
10048 + this->pool.age[i] = 0;
10049 + record->lnum = pos.lnum;
10050 + buf = this->pool.buf[i];
10058 + /* A plain breakpoint */
10059 + else if (line != NULL && (record->lnum = atoi((char *)line)) > 0
10060 + && source != NULL)
10062 + bp_file = obstack_strsave(obs, source);
10066 + * Edit the file or asm buffer
10067 + * when the table is reported by GDB as having changed
10068 + * or when this buffer is the frame buffer and the frame
10069 + * is invalid (because: we might be setting a frame in
10070 + * a newly disassembled buffer and must set again all
10071 + * its breakpoints)
10073 + if ((bp_file != NULL || buf != NULL)
10074 + && (this->bp_state & BPS_INVALID
10077 + && buf == this->fr_buf
10078 + && (this->bp_state & BPS_FR_INVALID)))
10081 + /* bufIsChanged is TRUE when previous gdb_edit_file() failed because
10082 + * the user cancelled the operation after having been warned the
10083 + * buffer is changed. In this case, do not try to gdb_edit_file()
10084 + * again for the next new breakpoints
10085 + * (as the operation is cancelled). */
10086 + if (! this->bufIsChanged)
10088 + if (gdb_edit_file(this, buf, bp_file, record->lnum, obs) != NULL)
10090 + /* MUST redraw the screen before calling update_debug_sign():
10091 + * update_debug_sign() invokes win_update()
10092 + * the screen might have been scrolled when Vim ask the
10093 + * user to confirm changes made to the previous buffer */
10094 + gdb_redraw(curwin->w_buffer);
10096 + record->buf = curwin->w_buffer;
10098 + if ((record->typenr =
10099 + gdb_define_sign(record->id, record->enabled)) != -1)
10101 + /* add bp sign */
10102 + buf_addsign(record->buf, BP_SIGN_ID(record->id),
10103 + record->lnum, record->typenr);
10104 + update_debug_sign(record->buf, record->lnum);
10106 + /* Set the frame sign again in case this is
10107 + * a newly disassembled buffer */
10108 + if (this->frame_pc != NULL
10110 + && this->fr_buf == NULL
10111 + && ! (record->buf->b_ml.ml_flags & ML_EMPTY))
10116 + obstack_strcat(obs, "^\\s*0x0*");
10117 + obstack_strcat0(obs, this->frame_pc);
10118 + ptrn = (char_u *)obstack_finish(obs);
10121 + && searchit(NULL, record->buf, &pos, FORWARD,
10122 + ptrn, 1L, SEARCH_KEEP, RE_LAST, (linenr_T)0, NULL) != FAIL)
10124 + gdb_fr_lite(this, record->buf, pos.lnum, obs);
10128 + /* Handle the case where bps are set after the frame sign:
10129 + * new disassembled code or reediting a wiped-out plain
10130 + * buffer or stepping in a newly disassembled buffer */
10131 + if (record->buf == this->fr_buf
10132 + && (this->bp_state & BPS_BP_HIT
10134 + && (this->bp_state & BPS_FR_INVALID)))
10136 + buf_findsign(this->fr_buf, FRAME_SIGN)) != 0)
10138 + /* remove frame sign and add it again on top
10139 + * of this new breakpoint */
10140 + if (lnum == record->lnum)
10141 + gdb_fr_lite(this, this->fr_buf, lnum, obs);
10143 + /* move back cursor to frame */
10144 + gdb_set_cursor(gdb_btowin(this->fr_buf), lnum);
10148 + record->next = this->tmplist; /* link to head of new table */
10149 + this->tmplist = record;
10150 + this->record = NULL; /* forget record */
10154 + this->bufIsChanged = bufIsChanged(curbuf);
10155 + win_goto(oldwin);
10164 + bpinfo_T *record = this->record;
10165 + char_u *bp_file = NULL;
10167 + bpinfo_T *p, **pt;
10173 + * Look for this breakpoint in previous list
10175 + for (pt = &(this->bpinfo); *pt != NULL; pt = &((*pt)->next))
10179 + /* The breakpoint number exists in the old table:
10180 + * remove old sign and replace by new one
10181 + * move the old record to tmplist and update its sign
10183 + if (record->id == p->id)
10185 + /* update enabled */
10186 + if (record->enabled != p->enabled)
10188 + p->enabled = record->enabled;
10189 + if ((p->typenr = gdb_define_bpsign(p, obs)) != -1)
10191 + cnb_buf_delsign(p->buf, BP_SIGN_ID(p->id));
10192 + cnb_buf_addsign(p->buf, BP_SIGN_ID(p->id), p->typenr, p->lnum, obs);
10196 + # ifdef BP_INVALID_ANO_MISSING
10197 + /* update disposition */
10198 + p->disposition = record->disposition;
10201 + /* update 'continue' */
10202 + p->cont = record->cont;
10204 + /* move from old list to new list */
10205 + *pt = p->next; /* unlink from old list */
10206 + p->next = this->tmplist; /* link to head of new table */
10207 + this->tmplist = p;
10208 + return; /* record may be reused */
10213 + * A new breakpoint number: edit the file if possible
10215 + /* An asm breakpoint */
10216 + if (address != NULL && at != NULL)
10218 + bp_file = obstack_strsave(obs, at);
10220 + /* Search all buffers in the asm buffer pool whose name starts
10221 + * with bp_file and find the one containing a line starting
10222 + * with address */
10223 + for (bufno = 1; ! cnb_outofbounds(bufno); bufno++)
10225 + if ((fname = cnb_filename(bufno)) != NULL
10226 + && STRSTR(fname, bp_file) != NULL
10227 + && (lnum = searchfor(fname, address)) > 0)
10229 + record->lnum = lnum;
10238 + /* A plain breakpoint */
10239 + else if (line != NULL && (record->lnum = atoi((char *)line)) > 0
10240 + && source != NULL)
10242 + bp_file = obstack_strsave(obs, source);
10246 + * Edit the file or asm buffer
10247 + * when the table is reported by GDB as having changed
10248 + * or when this buffer is the frame buffer and the frame
10249 + * is invalid (because: we might be setting a frame in
10250 + * a newly disassembled buffer and must set again all
10251 + * its breakpoints)
10253 + if ((bp_file != NULL || cnb_isvalid_buffer(buf))
10254 + && (this->bp_state & BPS_INVALID
10256 + && cnb_isvalid_buffer(buf)
10257 + && buf == this->fr_buf
10258 + && (this->bp_state & BPS_FR_INVALID)))
10261 + if ((record->buf = gdb_edit_file(buf, bp_file, record->lnum, 1, obs)) > 0)
10263 + if ((record->typenr = gdb_define_bpsign(record, obs)) != -1)
10265 + /* add bp sign */
10266 + cnb_buf_addsign(record->buf, BP_SIGN_ID(record->id),
10267 + record->typenr, record->lnum, obs);
10269 + /* Set the frame sign again in case this is
10270 + * a newly disassembled buffer */
10271 + if (this->frame_pc != NULL
10273 + && ! cnb_isvalid_buffer(this->fr_buf)
10274 + && (fname = cnb_filename(record->buf)) != NULL
10275 + && (lnum = searchfor(fname, this->frame_pc)) > 0)
10277 + gdb_fr_lite(this, record->buf, lnum, obs);
10280 + /* Handle the case where bps are set after the frame sign:
10281 + * new disassembled code or reediting a wiped-out plain
10282 + * buffer or stepping in a newly disassembled buffer */
10283 + if (record->buf == this->fr_buf
10284 + && (this->bp_state & BPS_BP_HIT
10286 + && (this->bp_state & BPS_FR_INVALID)))
10287 + && (lnum = find_fr_sign(this->fr_buf)) != 0)
10289 + /* remove frame sign and add it again on top
10290 + * of this new breakpoint */
10291 + if (lnum == record->lnum)
10292 + gdb_fr_lite(this, this->fr_buf, lnum, obs);
10296 + record->next = this->tmplist; /* link to head of new table */
10297 + this->tmplist = record;
10298 + this->record = NULL; /* forget record */
10304 + # endif /* FEAT_GDB */
10307 + * Parse str for annotation, set this->note.
10308 + * Return byte address following annotation, NULL if none found.
10309 + * Return byte address following ^Z^Z when unknown annotation.
10312 + parse_note(this, str)
10314 + char_u *str; /* string to parse */
10316 + char_u *note = NULL;
10317 + annotation_T *pt;
10320 + if (str != NULL && (note = STRSTR(str, "\032\032")) != NULL)
10322 + this->note = ANO_ANY;
10325 + for (pt = annotations; pt->str != NULL; pt++)
10327 + len = STRLEN(pt->str);
10329 + if (STRSTR(note, pt->str) == note
10330 + && (*(note + len) == NUL || isspace(*(note + len))))
10332 + this->note = pt->id;
10333 + return note + strlen((char *)pt->str);
10340 + # ifndef FEAT_GDB
10341 + /* Return annotation type of 'str' or ANO_NONE when not found. */
10343 + get_note(this, str)
10345 + char_u *str; /* string to parse */
10347 + int oldnote = this->note;
10348 + int note = ANO_NONE;
10350 + if (IS_ANNOTATION(str) && parse_note(this, str) != NULL)
10351 + note = this->note;
10353 + this->note = oldnote;
10356 + # endif /* FEAT_GDB */
10357 + # endif /* defined(GDB_LVL2_SUPPORT) || defined(GDB_LVL3_SUPPORT) */
10358 + #endif /* defined(FEAT_GDB) || defined(HAVE_CLEWN) */
10359 diff -c --new-file old/clewn/misc.c src/clewn/misc.c
10360 *** old/clewn/misc.c 1970-01-01 01:00:00.000000000 +0100
10361 --- src/clewn/misc.c 2008-10-11 16:29:18.000000000 +0200
10365 + /* vi:set ts=8 sts=4 sw=4:
10367 + * Copyright (C) 2004 Xavier de Gaye.
10369 + * This program is free software; you can redistribute it and/or modify
10370 + * it under the terms of the GNU General Public License as published by
10371 + * the Free Software Foundation; either version 2, or (at your option)
10372 + * any later version.
10374 + * This program is distributed in the hope that it will be useful,
10375 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10376 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10377 + * GNU General Public License for more details.
10379 + * You should have received a copy of the GNU General Public License
10380 + * along with this program (see the file COPYING); if not, write to the
10381 + * Free Software Foundation, Inc.,
10382 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
10384 + * $Id: misc.c 217 2008-10-11 14:29:18Z xavier $
10387 + #ifdef HAVE_CLEWN
10388 + # include <config.h>
10390 + # include <auto/config.h>
10391 + void vim_beep ();
10394 + #include <stdio.h>
10395 + #include <string.h>
10396 + #include <errno.h>
10397 + #include <ctype.h>
10398 + #include <sys/stat.h>
10400 + #ifdef HAVE_READLINE_READLINE_H
10401 + # include <readline/readline.h>
10404 + #ifdef HAVE_STDLIB_H
10405 + # include <stdlib.h>
10407 + #ifndef EXIT_FAILURE
10408 + # define EXIT_FAILURE 1
10411 + #ifdef HAVE_UNISTD_H
10412 + # include <unistd.h>
10415 + #ifdef HAVE_FCNTL_H
10416 + # include <fcntl.h>
10419 + #if !defined(HAVE_SYS_TIME_H) || defined(TIME_WITH_SYS_TIME)
10420 + # include <time.h> /* on some systems time.h should not be
10421 + included together with sys/time.h */
10423 + #ifdef HAVE_SYS_TIME_H
10424 + # include <sys/time.h>
10427 + #ifndef HAVE_SELECT
10428 + # ifdef HAVE_SYS_POLL_H
10429 + # include <sys/poll.h>
10431 + # ifdef HAVE_POLL_H
10432 + # include <poll.h>
10437 + /* Note: Some systems need both string.h and strings.h (Savage). However,
10438 + * some systems can't handle both, only use string.h in that case. */
10439 + #if defined(HAVE_STRINGS_H) && !defined(NO_STRINGS_WITH_STRING_H)
10440 + # include <strings.h>
10443 + #include "obstack.h"
10445 + # include "vim.h"
10447 + # include "clewn.h"
10450 + /* do not define xmalloc and family */
10451 + #undef GDB_MTRACE
10454 + #include "misc.h"
10456 + #if defined(__CYGWIN__) || defined(__CYGWIN32__)
10457 + # define WIN32UNIX /* Compiling for Win32 using Unix files. */
10458 + # define BINARY_FILE_IO
10459 + # undef HAVE_FCHDIR /* doesn't work well in most versions */
10462 + #if defined(HAVE_GETCWD) && defined(HAVE_GETWD)
10463 + # define USE_GETCWD
10466 + /* boolean constants */
10471 + * EMX doesn't have a global way of making open() use binary I/O.
10472 + * Use O_BINARY for all open() calls.
10474 + #if defined(__EMX__) || defined(__CYGWIN32__)
10475 + # define O_EXTRA O_BINARY
10477 + # define O_EXTRA 0
10480 + static void (*misc_abort)(void) = NULL; /* registered abort function */
10482 + /* Register an abort function for when allocating memory fails. */
10484 + xatabort(abort_func)
10485 + void (*abort_func)(void);
10487 + misc_abort = abort_func;
10490 + /* allocate memory */
10495 + void *value = malloc(size);
10499 + #ifdef HAVE_CLEWN
10500 + rl_cleanup_after_signal(); /* have readline reset terminal */
10501 + fprintf(stderr, "\nvirtual memory exhausted\n");
10503 + if (misc_abort != NULL)
10506 + exit(EXIT_FAILURE);
10511 + /* Allocate memory and set all bytes to zero */
10516 + void *p = xmalloc(size);
10517 + clewn_memset(p, 0, size);
10521 + /* Changes the size of the memory block pointed to by ptr to size bytes. */
10523 + xrealloc(ptr, size)
10527 + void *value = realloc(ptr, size);
10531 + #ifdef HAVE_CLEWN
10532 + rl_cleanup_after_signal(); /* have readline reset terminal */
10533 + fprintf(stderr, "\nvirtual memory exhausted\n");
10535 + if (misc_abort != NULL)
10538 + exit(EXIT_FAILURE);
10543 + /* Replacement for free() that ignores NULL pointers. */
10552 + #ifndef HAVE_MEMSET
10554 + clewn_memset(ptr, c, size)
10561 + while (size-- > 0)
10567 + #ifdef CLEWN_MEMMOVE
10569 + * Version of memmove() that handles overlapping source and destination.
10570 + * For systems that don't have a function that is guaranteed to do that (SYSV).
10573 + clewn_memmove(d, s, len)
10578 + /* a void doesn't have a size, we use char pointers */
10582 + /* overlap, copy backwards */
10583 + if (dst > src && dst < src + len)
10587 + while (len-- > 0)
10590 + else /* copy forwards */
10591 + while (len-- > 0)
10596 + /* copy a string into newly allocated memory */
10598 + clewn_strsave(string)
10604 + if (string != NULL) {
10605 + len = strlen(string) + 1;
10606 + p = xmalloc(len);
10607 + clewn_memmove(p, string, len);
10617 + clewn_strnsave(string, len)
10621 + char *p = xmalloc(len + 1);
10624 + if (string != NULL)
10625 + strncpy(p, string, len);
10626 + *(p + len) = '\0';
10631 + clewn_sleep(msec)
10635 + * Everybody sleeps in a different way...
10636 + * Prefer nanosleep(), some versions of usleep() can only sleep up to
10639 + #ifdef HAVE_NANOSLEEP
10641 + struct timespec ts;
10643 + ts.tv_sec = msec / 1000;
10644 + ts.tv_nsec = (msec % 1000) * 1000000;
10645 + (void)nanosleep(&ts, NULL);
10648 + # ifdef HAVE_USLEEP
10649 + while (msec >= 1000)
10651 + usleep((999 * 1000));
10654 + usleep((msec * 1000));
10656 + # ifndef HAVE_SELECT
10657 + poll(NULL, 0, msec);
10663 + struct timeval tv;
10665 + tv.tv_sec = msec / 1000;
10666 + tv.tv_usec = (msec % 1000) * 1000;
10668 + * NOTE: Solaris 2.6 has a bug that makes select() hang here. Get
10669 + * a patch from Sun to fix this. Reported by Gunnar Pedersen.
10671 + select(0, NULL, NULL, NULL, &tv);
10673 + # endif /* __EMX__ */
10674 + # endif /* HAVE_SELECT */
10675 + # endif /* HAVE_NANOSLEEP */
10676 + #endif /* HAVE_USLEEP */
10679 + /* Give a warning for an error. */
10683 + #ifdef HAVE_CLEWN
10684 + /* use readline utility */
10685 + # ifdef HAVE_RL_DING
10688 + ding(); /* deprecated */
10696 + * Get name of current directory into buffer 'buf' of length 'len' bytes.
10697 + * Return 1 for success, 0 for failure.
10700 + clewn_getwd(buf, len)
10704 + #if defined(USE_GETCWD)
10705 + if (getcwd(buf, len) == NULL)
10707 + strcpy(buf, strerror(errno));
10712 + return (getwd(buf) != NULL ? 1 : 0);
10717 + * Get absolute file name into buffer 'buf' of length 'len' bytes.
10718 + * return 0 for failure, 1 for success
10721 + clewn_fullpath(fname, buf, len, force)
10725 + int force; /* also expand when already absolute path */
10728 + #ifdef HAVE_FCHDIR
10730 + static int dont_fchdir = FALSE; /* TRUE when fchdir() doesn't work */
10732 + char olddir[MAXPATHL];
10737 + if (fname == NULL)
10740 + /* expand it if forced or not an absolute path */
10741 + if (force || *fname != '/')
10744 + * If the file name has a path, change to that directory for a moment,
10745 + * and then do the getwd() (and get back to where we were).
10746 + * This will get the correct path name with "../" things.
10748 + if ((p = strrchr(fname, '/')) != NULL)
10750 + #ifdef HAVE_FCHDIR
10752 + * Use fchdir() if possible, it's said to be faster and more
10753 + * reliable. But on SunOS 4 it might not work. Check this by
10754 + * doing a fchdir() right now.
10756 + if (!dont_fchdir)
10758 + fd = open(".", O_RDONLY | O_EXTRA, 0);
10759 + if (fd >= 0 && fchdir(fd) < 0)
10763 + dont_fchdir = TRUE; /* don't try again */
10768 + /* Only change directory when we are sure we can return to where
10769 + * we are now. After doing "su" chdir(".") might not work. */
10771 + #ifdef HAVE_FCHDIR
10774 + (clewn_getwd(olddir, MAXPATHL) == 0
10775 + || chdir((char *)olddir) != 0))
10777 + p = NULL; /* can't get current dir: don't chdir */
10782 + /* The directory is copied into buf[], to be able to remove
10783 + * the file name without changing it (could be a string in
10784 + * read-only memory) */
10785 + if (p - fname >= len)
10789 + strncpy(buf, fname, p - fname);
10790 + buf[p - fname] = '\0';
10791 + if (chdir((char *)buf))
10800 + if (clewn_getwd(buf, len) == 0)
10808 + #ifdef HAVE_FCHDIR
10811 + (void)fchdir(fd);
10816 + (void)chdir((char *)olddir);
10824 + if (l > 0 && buf[l - 1] != '/' && *fname != '\0')
10825 + strcat(buf, "/");
10829 + /* catch file names which are too long */
10830 + if (retval == 0 || ((int)(strlen(buf) + strlen(fname)) >= len))
10833 + strcat(buf, fname);
10839 + * Get a full path name for the file named 'name'.
10840 + * If name is an absolute path, just stat it. Otherwise, add name to
10841 + * each directory in GDB source directories and stat the result.
10844 + get_fullpath(name, sourcedir, source_cur, source_list, obs)
10845 + char *name; /* file name */
10846 + char *sourcedir; /* GDB source directories */
10847 + char *source_cur; /* GDB current source */
10848 + char *source_list; /* GDB source list */
10849 + struct obstack *obs;
10852 + char pathbuf[MAXPATHL];
10861 + if (name == NULL || *name == NUL)
10864 + /* an absolute path name */
10865 + if (*name == '/')
10867 + if (stat((char *)name, &st) == 0)
10870 + /* strip off the directory part and continue */
10871 + name = strrchr(name, '/') + 1;
10874 + if (sourcedir == NULL) /* use current working directory */
10875 + sourcedir = GDB_CWD;
10877 + /* proceed with each directory in GDB source directories */
10881 + if ((last = strchr(ptr, ':')) != NULL)
10884 + if (strcmp(ptr, GDB_CDIR) == 0) /* compilation directory */
10886 + /* hay: file="NAME",fullname=" */
10887 + obstack_strcat(obs, "file=\"");
10888 + obstack_strcat(obs, name);
10889 + obstack_strcat0(obs, "\",fullname=\"");
10890 + hay = (char *)obstack_finish(obs);
10892 + /* name is the current sourcefile: use gdb compilation directory */
10893 + if (source_cur != NULL && (found=strstr(source_cur, hay)) != NULL ){
10894 + found += strlen(hay);
10895 + if ((end=strstr(found, "\"")) != NULL)
10896 + return (char *)obstack_copy0(obs, found, end - found);
10899 + /* lookup for first occurence of name in source list */
10900 + if (source_list != NULL && (found=strstr(source_list, hay)) != NULL ){
10901 + found += strlen(hay);
10902 + if ((end=strstr(found, "\"")) != NULL)
10903 + return (char *)obstack_copy0(obs, found, end - found);
10908 + else if (strcmp(ptr, GDB_CWD) == 0) /* current working directory */
10910 + if (clewn_getwd(pathbuf, MAXPATHL))
10920 + obstack_strcat(obs, dir);
10921 + obstack_strcat(obs, "/");
10922 + obstack_strcat0(obs, name);
10923 + pathname = (char *)obstack_finish(obs);
10925 + if (stat((char *)pathname, &st) == 0) {
10926 + /* need to handle the case where the path includes '..'
10927 + * for example "/home/xavier/tmp/.." must be converted
10928 + * to "/home/xavier" */
10929 + if (clewn_fullpath(pathname, pathbuf, MAXPATHL, TRUE))
10930 + return (char *)obstack_strsave(obs, pathbuf);
10935 + } while (ptr != NULL && *ptr != NUL);
10941 + * Execute a program with (optionnaly quoted) arguments
10947 + char ** argv = NULL; /* keep compiler happy */
10954 + if ((newcmd = clewn_strsave(cmd)) == NULL)
10958 + * step 1: find number of arguments
10959 + * step 2: separate them and built argv[]
10961 + for (i = 0; i < 2; i++)
10970 + while (*ptr == ' ' || *ptr == '\t') /* skip to next non-white */
10973 + if (*ptr == '\0')
10976 + if (*ptr == '"' || *ptr == '\'')
10983 + argv[argc] = ptr;
10986 + while (*ptr && (inquote || (*ptr != ' ' && *ptr != '\t')))
10988 + if (*ptr == '"' || *ptr == '\'')
10994 + if (*ptr == '\0')
11003 + /* got the number of arguments */
11004 + if (i == 0 && (argv = (char **) xcalloc((size_t)((argc + 1) * sizeof(char *)))) == NULL)
11008 + execvp(argv[0], argv);
11010 diff -c --new-file old/clewn/misc.h src/clewn/misc.h
11011 *** old/clewn/misc.h 1970-01-01 01:00:00.000000000 +0100
11012 --- src/clewn/misc.h 2007-07-21 18:35:40.000000000 +0200
11016 + /* vi:set ts=8 sts=4 sw=4:
11018 + * Copyright (C) 2004 Xavier de Gaye.
11020 + * This program is free software; you can redistribute it and/or modify
11021 + * it under the terms of the GNU General Public License as published by
11022 + * the Free Software Foundation; either version 2, or (at your option)
11023 + * any later version.
11025 + * This program is distributed in the hope that it will be useful,
11026 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
11027 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11028 + * GNU General Public License for more details.
11030 + * You should have received a copy of the GNU General Public License
11031 + * along with this program (see the file COPYING); if not, write to the
11032 + * Free Software Foundation, Inc.,
11033 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
11035 + * $Id: misc.h 148 2007-07-21 16:35:40Z xavier $
11042 + /* The AIX VisualAge cc compiler defines __EXTENDED__ instead of __STDC__
11043 + * because it includes pre-ansi features. */
11044 + # if defined(__STDC__) || defined(__GNUC__) || defined(__EXTENDED__)
11045 + # define __ARGS(x) x
11047 + # define __ARGS(x) ()
11051 + /* memmove is not present on all systems, use memmove, bcopy, memcpy or our
11053 + /* Some systems have (void *) arguments, some (char *). If we use (char *) it
11054 + * works for all */
11055 + #ifdef USEMEMMOVE
11056 + # define clewn_memmove(to, from, len) memmove((char *)(to), (char *)(from), len)
11059 + # define clewn_memmove(to, from, len) bcopy((char *)(from), (char *)(to), len)
11061 + # ifdef USEMEMCPY
11062 + # define clewn_memmove(to, from, len) memcpy((char *)(to), (char *)(from), len)
11064 + # define CLEWN_MEMMOVE
11065 + void clewn_memmove __ARGS((void *, void *, size_t));
11070 + #ifdef HAVE_MEMSET
11071 + # define clewn_memset(ptr, c, size) memset((ptr), (c), (size))
11073 + void *clewn_memset __ARGS((void *, int, size_t));
11077 + * Maximum length of a path (for non-unix systems) Make it a bit long, to stay
11078 + * on the safe side. But not too long to put on the stack.
11081 + # ifdef MAXPATHLEN
11082 + # define MAXPATHL MAXPATHLEN
11084 + # define MAXPATHL 256
11088 + /* gdb directory constants */
11089 + #define GDB_CDIR "$cdir"
11090 + #define GDB_CWD "$cwd"
11092 + void xatabort __ARGS((void (*)(void)));
11093 + void * xmalloc __ARGS((size_t));
11094 + void * xcalloc __ARGS((size_t));
11095 + void * xrealloc __ARGS((void *, size_t));
11096 + void xfree __ARGS((void *));
11097 + char * clewn_strsave __ARGS((char *));
11098 + char * clewn_strnsave __ARGS((char *, size_t));
11099 + void clewn_sleep __ARGS((int));
11100 + void clewn_beep __ARGS((void));
11101 + int clewn_getwd __ARGS((char *, int));
11102 + int clewn_fullpath __ARGS((char *, char *, int, int));
11103 + char * get_fullpath __ARGS((char *, char *, char *, char *, struct obstack *));
11104 + void clewn_exec(char *);
11106 + #endif /* MISC_H */
11108 diff -c --new-file old/clewn/obstack.c src/clewn/obstack.c
11109 *** old/clewn/obstack.c 1970-01-01 01:00:00.000000000 +0100
11110 --- src/clewn/obstack.c 2008-10-11 16:29:18.000000000 +0200
11114 + /* obstack.c - subroutines used implicitly by object stack macros
11115 + Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
11116 + 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
11117 + This file is part of the GNU C Library.
11119 + The GNU C Library is free software; you can redistribute it and/or
11120 + modify it under the terms of the GNU Lesser General Public
11121 + License as published by the Free Software Foundation; either
11122 + version 2.1 of the License, or (at your option) any later version.
11124 + The GNU C Library is distributed in the hope that it will be useful,
11125 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11126 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11127 + Lesser General Public License for more details.
11129 + You should have received a copy of the GNU Lesser General Public
11130 + License along with the GNU C Library; if not, write to the Free
11131 + Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
11132 + Boston, MA 02110-1301, USA. */
11136 + # include <obstack.h>
11137 + # include <shlib-compat.h>
11139 + # ifdef HAVE_CONFIG_H
11140 + # ifdef HAVE_CLEWN
11141 + # include <config.h>
11143 + # include <auto/config.h>
11146 + # include <stdint.h>
11147 + # include "obstack.h"
11150 + /* NOTE BEFORE MODIFYING THIS FILE: This version number must be
11151 + incremented whenever callers compiled using an old obstack.h can no
11152 + longer properly call the functions in this obstack.c. */
11153 + #define OBSTACK_INTERFACE_VERSION 1
11155 + /* Comment out all this code if we are using the GNU C Library, and are not
11156 + actually compiling the library itself, and the installed library
11157 + supports the same library interface we do. This code is part of the GNU
11158 + C Library, but also included in many other GNU distributions. Compiling
11159 + and linking in this code is a waste when using the GNU C library
11160 + (especially if it is a shared library). Rather than having every GNU
11161 + program understand `configure --with-gnu-libc' and omit the object
11162 + files, it is simpler to just do this in the source for each such file. */
11164 + #include <stdio.h> /* Random thing to get __GNU_LIBRARY__. */
11165 + #if !defined _LIBC && defined __GNU_LIBRARY__ && __GNU_LIBRARY__ > 1
11166 + # include <gnu-versions.h>
11167 + # if _GNU_OBSTACK_INTERFACE_VERSION == OBSTACK_INTERFACE_VERSION
11168 + # define ELIDE_CODE
11172 + #include <stddef.h>
11174 + #ifndef ELIDE_CODE
11177 + # if HAVE_INTTYPES_H
11178 + # include <inttypes.h>
11180 + # if HAVE_STDINT_H || defined _LIBC
11181 + # include <stdint.h>
11184 + /* Determine default alignment. */
11194 + union fooround u;
11196 + /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
11197 + But in fact it might be less smart and round addresses to as much as
11198 + DEFAULT_ROUNDING. So we prepare for it to do that. */
11201 + DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
11202 + DEFAULT_ROUNDING = sizeof (union fooround)
11205 + /* When we copy a long block of data, this is the unit to do it with.
11206 + On some machines, copying successive ints does not work;
11207 + in such a case, redefine COPYING_UNIT to `long' (if that works)
11208 + or `char' as a last resort. */
11209 + # ifndef COPYING_UNIT
11210 + # define COPYING_UNIT int
11214 + /* The functions allocating more room by calling `obstack_chunk_alloc'
11215 + jump to the handler pointed to by `obstack_alloc_failed_handler'.
11216 + This can be set to a user defined function which should either
11217 + abort gracefully or use longjump - but shouldn't return. This
11218 + variable by default points to the internal function
11219 + `print_and_abort'. */
11220 + static void print_and_abort (void);
11221 + void (*obstack_alloc_failed_handler) (void) = print_and_abort;
11223 + /* Exit value used when `print_and_abort' is used. */
11224 + # include <stdlib.h>
11226 + int obstack_exit_failure = EXIT_FAILURE;
11228 + # define obstack_exit_failure EXIT_FAILURE
11232 + # if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4)
11233 + /* A looong time ago (before 1994, anyway; we're not sure) this global variable
11234 + was used by non-GNU-C macros to avoid multiple evaluation. The GNU C
11235 + library still exports it because somebody might use it. */
11236 + struct obstack *_obstack_compat;
11237 + compat_symbol (libc, _obstack_compat, _obstack, GLIBC_2_0);
11241 + /* Define a macro that either calls functions with the traditional malloc/free
11242 + calling interface, or calls functions with the mmalloc/mfree interface
11243 + (that adds an extra first argument), based on the state of use_extra_arg.
11244 + For free, do not use ?:, since some compilers, like the MIPS compilers,
11245 + do not allow (expr) ? void : void. */
11247 + # define CALL_CHUNKFUN(h, size) \
11248 + (((h) -> use_extra_arg) \
11249 + ? (*(h)->chunkfun) ((h)->extra_arg, (size)) \
11250 + : (*(struct _obstack_chunk *(*) (long)) (h)->chunkfun) ((size)))
11252 + # define CALL_FREEFUN(h, old_chunk) \
11254 + if ((h) -> use_extra_arg) \
11255 + (*(h)->freefun) ((h)->extra_arg, (old_chunk)); \
11257 + (*(void (*) (void *)) (h)->freefun) ((old_chunk)); \
11261 + /* Initialize an obstack H for use. Specify chunk size SIZE (0 means default).
11262 + Objects start on multiples of ALIGNMENT (0 means use default).
11263 + CHUNKFUN is the function to use to allocate chunks,
11264 + and FREEFUN the function to free them.
11266 + Return nonzero if successful, calls obstack_alloc_failed_handler if
11267 + allocation fails. */
11270 + _obstack_begin (struct obstack *h,
11271 + int size, int alignment,
11272 + void *(*chunkfun) (long),
11273 + void (*freefun) (void *))
11275 + register struct _obstack_chunk *chunk; /* points to new chunk */
11277 + if (alignment == 0)
11278 + alignment = DEFAULT_ALIGNMENT;
11280 + /* Default size is what GNU malloc can fit in a 4096-byte block. */
11282 + /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
11283 + Use the values for range checking, because if range checking is off,
11284 + the extra bytes won't be missed terribly, but if range checking is on
11285 + and we used a larger request, a whole extra 4096 bytes would be
11288 + These number are irrelevant to the new GNU malloc. I suspect it is
11289 + less sensitive to the size of the request. */
11290 + int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
11291 + + 4 + DEFAULT_ROUNDING - 1)
11292 + & ~(DEFAULT_ROUNDING - 1));
11293 + size = 4096 - extra;
11296 + h->chunkfun = (struct _obstack_chunk * (*)(void *, long)) chunkfun;
11297 + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
11298 + h->chunk_size = size;
11299 + h->alignment_mask = alignment - 1;
11300 + h->use_extra_arg = 0;
11302 + chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
11304 + (*obstack_alloc_failed_handler) ();
11305 + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
11307 + h->chunk_limit = chunk->limit
11308 + = (char *) chunk + h->chunk_size;
11310 + /* The initial chunk now contains no empty object. */
11311 + h->maybe_empty_object = 0;
11312 + h->alloc_failed = 0;
11317 + _obstack_begin_1 (struct obstack *h, int size, int alignment,
11318 + void *(*chunkfun) (void *, long),
11319 + void (*freefun) (void *, void *),
11322 + register struct _obstack_chunk *chunk; /* points to new chunk */
11324 + if (alignment == 0)
11325 + alignment = DEFAULT_ALIGNMENT;
11327 + /* Default size is what GNU malloc can fit in a 4096-byte block. */
11329 + /* 12 is sizeof (mhead) and 4 is EXTRA from GNU malloc.
11330 + Use the values for range checking, because if range checking is off,
11331 + the extra bytes won't be missed terribly, but if range checking is on
11332 + and we used a larger request, a whole extra 4096 bytes would be
11335 + These number are irrelevant to the new GNU malloc. I suspect it is
11336 + less sensitive to the size of the request. */
11337 + int extra = ((((12 + DEFAULT_ROUNDING - 1) & ~(DEFAULT_ROUNDING - 1))
11338 + + 4 + DEFAULT_ROUNDING - 1)
11339 + & ~(DEFAULT_ROUNDING - 1));
11340 + size = 4096 - extra;
11343 + h->chunkfun = (struct _obstack_chunk * (*)(void *,long)) chunkfun;
11344 + h->freefun = (void (*) (void *, struct _obstack_chunk *)) freefun;
11345 + h->chunk_size = size;
11346 + h->alignment_mask = alignment - 1;
11347 + h->extra_arg = arg;
11348 + h->use_extra_arg = 1;
11350 + chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
11352 + (*obstack_alloc_failed_handler) ();
11353 + h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
11355 + h->chunk_limit = chunk->limit
11356 + = (char *) chunk + h->chunk_size;
11358 + /* The initial chunk now contains no empty object. */
11359 + h->maybe_empty_object = 0;
11360 + h->alloc_failed = 0;
11364 + /* Allocate a new current chunk for the obstack *H
11365 + on the assumption that LENGTH bytes need to be added
11366 + to the current object, or a new object of length LENGTH allocated.
11367 + Copies any partial object from the end of the old chunk
11368 + to the beginning of the new one. */
11371 + _obstack_newchunk (struct obstack *h, int length)
11373 + register struct _obstack_chunk *old_chunk = h->chunk;
11374 + register struct _obstack_chunk *new_chunk;
11375 + register long new_size;
11376 + register long obj_size = h->next_free - h->object_base;
11379 + char *object_base;
11381 + /* Compute size for new chunk. */
11382 + new_size = (obj_size + length) + (obj_size >> 3) + h->alignment_mask + 100;
11383 + if (new_size < h->chunk_size)
11384 + new_size = h->chunk_size;
11386 + /* Allocate and initialize the new chunk. */
11387 + new_chunk = CALL_CHUNKFUN (h, new_size);
11389 + (*obstack_alloc_failed_handler) ();
11390 + h->chunk = new_chunk;
11391 + new_chunk->prev = old_chunk;
11392 + new_chunk->limit = h->chunk_limit = (char *) new_chunk + new_size;
11394 + /* Compute an aligned object_base in the new chunk */
11396 + __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
11398 + /* Move the existing object to the new chunk.
11399 + Word at a time is fast and is safe if the object
11400 + is sufficiently aligned. */
11401 + if (h->alignment_mask + 1 >= DEFAULT_ALIGNMENT)
11403 + for (i = obj_size / sizeof (COPYING_UNIT) - 1;
11405 + ((COPYING_UNIT *)object_base)[i]
11406 + = ((COPYING_UNIT *)h->object_base)[i];
11407 + /* We used to copy the odd few remaining bytes as one extra COPYING_UNIT,
11408 + but that can cross a page boundary on a machine
11409 + which does not do strict alignment for COPYING_UNITS. */
11410 + already = obj_size / sizeof (COPYING_UNIT) * sizeof (COPYING_UNIT);
11414 + /* Copy remaining bytes one by one. */
11415 + for (i = already; i < obj_size; i++)
11416 + object_base[i] = h->object_base[i];
11418 + /* If the object just copied was the only data in OLD_CHUNK,
11419 + free that chunk and remove it from the chain.
11420 + But not if that chunk might contain an empty object. */
11421 + if (! h->maybe_empty_object
11422 + && (h->object_base
11423 + == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
11424 + h->alignment_mask)))
11426 + new_chunk->prev = old_chunk->prev;
11427 + CALL_FREEFUN (h, old_chunk);
11430 + h->object_base = object_base;
11431 + h->next_free = h->object_base + obj_size;
11432 + /* The new chunk certainly contains no empty object yet. */
11433 + h->maybe_empty_object = 0;
11436 + libc_hidden_def (_obstack_newchunk)
11439 + /* Return nonzero if object OBJ has been allocated from obstack H.
11440 + This is here for debugging.
11441 + If you use it in a program, you are probably losing. */
11443 + /* Suppress -Wmissing-prototypes warning. We don't want to declare this in
11444 + obstack.h because it is just for debugging. */
11445 + int _obstack_allocated_p (struct obstack *h, void *obj);
11448 + _obstack_allocated_p (struct obstack *h, void *obj)
11450 + register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
11451 + register struct _obstack_chunk *plp; /* point to previous chunk if any */
11454 + /* We use >= rather than > since the object cannot be exactly at
11455 + the beginning of the chunk but might be an empty object exactly
11456 + at the end of an adjacent chunk. */
11457 + while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
11465 + /* Free objects in obstack H, including OBJ and everything allocate
11466 + more recently than OBJ. If OBJ is zero, free everything in H. */
11468 + # undef obstack_free
11471 + obstack_free (struct obstack *h, void *obj)
11473 + register struct _obstack_chunk *lp; /* below addr of any objects in this chunk */
11474 + register struct _obstack_chunk *plp; /* point to previous chunk if any */
11477 + /* We use >= because there cannot be an object at the beginning of a chunk.
11478 + But there can be an empty object at that address
11479 + at the end of another chunk. */
11480 + while (lp != 0 && ((void *) lp >= obj || (void *) (lp)->limit < obj))
11483 + CALL_FREEFUN (h, lp);
11485 + /* If we switch chunks, we can't tell whether the new current
11486 + chunk contains an empty object, so assume that it may. */
11487 + h->maybe_empty_object = 1;
11491 + h->object_base = h->next_free = (char *) (obj);
11492 + h->chunk_limit = lp->limit;
11495 + else if (obj != 0)
11496 + /* obj is not in any of the chunks! */
11501 + /* Older versions of libc used a function _obstack_free intended to be
11502 + called by non-GCC compilers. */
11503 + strong_alias (obstack_free, _obstack_free)
11507 + _obstack_memory_used (struct obstack *h)
11509 + register struct _obstack_chunk* lp;
11510 + register int nbytes = 0;
11512 + for (lp = h->chunk; lp != 0; lp = lp->prev)
11514 + nbytes += lp->limit - (char *) lp;
11519 + /* Define the error handler. */
11521 + # include <libintl.h>
11524 + # define _(msgid) (msgid)
11528 + # include <libio/iolibio.h>
11531 + # ifndef __attribute__
11532 + /* This feature is available in gcc versions 2.5 and later. */
11533 + # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
11534 + # define __attribute__(Spec) /* empty */
11539 + __attribute__ ((noreturn))
11540 + print_and_abort (void)
11542 + /* Don't change any of these strings. Yes, it would be possible to add
11543 + the newline to the string and use fputs or so. But this must not
11544 + happen because the "memory exhausted" message appears in other places
11545 + like this and the translation should be reused instead of creating
11546 + a very similar string which requires a separate translation. */
11548 + (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
11550 + fprintf (stderr, "%s\n", _("memory exhausted"));
11552 + exit (obstack_exit_failure);
11555 + #endif /* !ELIDE_CODE */
11556 diff -c --new-file old/clewn/obstack.h src/clewn/obstack.h
11557 *** old/clewn/obstack.h 1970-01-01 01:00:00.000000000 +0100
11558 --- src/clewn/obstack.h 2006-07-29 19:19:30.000000000 +0200
11562 + /* obstack.h - object stack macros
11563 + Copyright (C) 1988-1994,1996-1999,2003,2004,2005
11564 + Free Software Foundation, Inc.
11565 + This file is part of the GNU C Library.
11567 + The GNU C Library is free software; you can redistribute it and/or
11568 + modify it under the terms of the GNU Lesser General Public
11569 + License as published by the Free Software Foundation; either
11570 + version 2.1 of the License, or (at your option) any later version.
11572 + The GNU C Library is distributed in the hope that it will be useful,
11573 + but WITHOUT ANY WARRANTY; without even the implied warranty of
11574 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11575 + Lesser General Public License for more details.
11577 + You should have received a copy of the GNU Lesser General Public
11578 + License along with the GNU C Library; if not, write to the Free
11579 + Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
11580 + Boston, MA 02110-1301, USA. */
11584 + All the apparent functions defined here are macros. The idea
11585 + is that you would use these pre-tested macros to solve a
11586 + very specific set of problems, and they would run fast.
11587 + Caution: no side-effects in arguments please!! They may be
11588 + evaluated MANY times!!
11590 + These macros operate a stack of objects. Each object starts life
11591 + small, and may grow to maturity. (Consider building a word syllable
11592 + by syllable.) An object can move while it is growing. Once it has
11593 + been "finished" it never changes address again. So the "top of the
11594 + stack" is typically an immature growing object, while the rest of the
11595 + stack is of mature, fixed size and fixed address objects.
11597 + These routines grab large chunks of memory, using a function you
11598 + supply, called `obstack_chunk_alloc'. On occasion, they free chunks,
11599 + by calling `obstack_chunk_free'. You must define them and declare
11600 + them before using any obstack macros.
11602 + Each independent stack is represented by a `struct obstack'.
11603 + Each of the obstack macros expects a pointer to such a structure
11604 + as the first argument.
11606 + One motivation for this package is the problem of growing char strings
11607 + in symbol tables. Unless you are "fascist pig with a read-only mind"
11608 + --Gosper's immortal quote from HAKMEM item 154, out of context--you
11609 + would not like to put any arbitrary upper limit on the length of your
11612 + In practice this often means you will build many short symbols and a
11613 + few long symbols. At the time you are reading a symbol you don't know
11614 + how long it is. One traditional method is to read a symbol into a
11615 + buffer, realloc()ating the buffer every time you try to read a symbol
11616 + that is longer than the buffer. This is beaut, but you still will
11617 + want to copy the symbol from the buffer to a more permanent
11618 + symbol-table entry say about half the time.
11620 + With obstacks, you can work differently. Use one obstack for all symbol
11621 + names. As you read a symbol, grow the name in the obstack gradually.
11622 + When the name is complete, finalize it. Then, if the symbol exists already,
11623 + free the newly read name.
11625 + The way we do this is to take a large chunk, allocating memory from
11626 + low addresses. When you want to build a symbol in the chunk you just
11627 + add chars above the current "high water mark" in the chunk. When you
11628 + have finished adding chars, because you got to the end of the symbol,
11629 + you know how long the chars are, and you can create a new object.
11630 + Mostly the chars will not burst over the highest address of the chunk,
11631 + because you would typically expect a chunk to be (say) 100 times as
11632 + long as an average object.
11634 + In case that isn't clear, when we have enough chars to make up
11635 + the object, THEY ARE ALREADY CONTIGUOUS IN THE CHUNK (guaranteed)
11636 + so we just point to it where it lies. No moving of chars is
11637 + needed and this is the second win: potentially long strings need
11638 + never be explicitly shuffled. Once an object is formed, it does not
11639 + change its address during its lifetime.
11641 + When the chars burst over a chunk boundary, we allocate a larger
11642 + chunk, and then copy the partly formed object from the end of the old
11643 + chunk to the beginning of the new larger chunk. We then carry on
11644 + accreting characters to the end of the object as we normally would.
11646 + A special macro is provided to add a single char at a time to a
11647 + growing object. This allows the use of register variables, which
11648 + break the ordinary 'growth' macro.
11651 + We allocate large chunks.
11652 + We carve out one object at a time from the current chunk.
11653 + Once carved, an object never moves.
11654 + We are free to append data of any size to the currently
11656 + Exactly one object is growing in an obstack at any one time.
11657 + You can run one obstack per control block.
11658 + You may have as many control blocks as you dare.
11659 + Because of the way we do it, you can `unwind' an obstack
11660 + back to a previous state. (You may remove objects much
11661 + as you would with a stack.)
11665 + /* Don't do the contents of this file more than once. */
11667 + #ifndef _OBSTACK_H
11668 + #define _OBSTACK_H 1
11670 + #ifdef __cplusplus
11674 + /* We need the type of a pointer subtraction. If __PTRDIFF_TYPE__ is
11675 + defined, as with GNU C, use that; that way we don't pollute the
11676 + namespace with <stddef.h>'s symbols. Otherwise, include <stddef.h>
11677 + and use ptrdiff_t. */
11679 + #ifdef __PTRDIFF_TYPE__
11680 + # define PTR_INT_TYPE __PTRDIFF_TYPE__
11682 + # include <stddef.h>
11683 + # define PTR_INT_TYPE ptrdiff_t
11686 + /* If B is the base of an object addressed by P, return the result of
11687 + aligning P to the next multiple of A + 1. B and P must be of type
11688 + char *. A + 1 must be a power of 2. */
11690 + #define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
11692 + /* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
11693 + where pointers can be converted to integers, aligned as integers,
11694 + and converted back again. If PTR_INT_TYPE is narrower than a
11695 + pointer (e.g., the AS/400), play it safe and compute the alignment
11696 + relative to B. Otherwise, use the faster strategy of computing the
11697 + alignment relative to 0. */
11699 + #define __PTR_ALIGN(B, P, A) \
11700 + __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
11703 + #include <string.h>
11705 + struct _obstack_chunk /* Lives at front of each chunk. */
11707 + char *limit; /* 1 past end of this chunk */
11708 + struct _obstack_chunk *prev; /* address of prior chunk or NULL */
11709 + char contents[4]; /* objects begin here */
11712 + struct obstack /* control current object in current chunk */
11714 + long chunk_size; /* preferred size to allocate chunks in */
11715 + struct _obstack_chunk *chunk; /* address of current struct obstack_chunk */
11716 + char *object_base; /* address of object we are building */
11717 + char *next_free; /* where to add next char to current object */
11718 + char *chunk_limit; /* address of char after current chunk */
11721 + PTR_INT_TYPE tempint;
11723 + } temp; /* Temporary for some macros. */
11724 + int alignment_mask; /* Mask of alignment for each object. */
11725 + /* These prototypes vary based on `use_extra_arg', and we use
11726 + casts to the prototypeless function type in all assignments,
11727 + but having prototypes here quiets -Wstrict-prototypes. */
11728 + struct _obstack_chunk *(*chunkfun) (void *, long);
11729 + void (*freefun) (void *, struct _obstack_chunk *);
11730 + void *extra_arg; /* first arg for chunk alloc/dealloc funcs */
11731 + unsigned use_extra_arg:1; /* chunk alloc/dealloc funcs take extra arg */
11732 + unsigned maybe_empty_object:1;/* There is a possibility that the current
11733 + chunk contains a zero-length object. This
11734 + prevents freeing the chunk if we allocate
11735 + a bigger chunk to replace it. */
11736 + unsigned alloc_failed:1; /* No longer used, as we now call the failed
11737 + handler on error, but retained for binary
11738 + compatibility. */
11741 + /* Declare the external functions we use; they are in obstack.c. */
11743 + extern void _obstack_newchunk (struct obstack *, int);
11744 + extern int _obstack_begin (struct obstack *, int, int,
11745 + void *(*) (long), void (*) (void *));
11746 + extern int _obstack_begin_1 (struct obstack *, int, int,
11747 + void *(*) (void *, long),
11748 + void (*) (void *, void *), void *);
11749 + extern int _obstack_memory_used (struct obstack *);
11751 + void obstack_free (struct obstack *obstack, void *block);
11754 + /* Error handler called when `obstack_chunk_alloc' failed to allocate
11755 + more memory. This can be set to a user defined function which
11756 + should either abort gracefully or use longjump - but shouldn't
11757 + return. The default action is to print a message and abort. */
11758 + extern void (*obstack_alloc_failed_handler) (void);
11760 + /* Exit value used when `print_and_abort' is used. */
11761 + extern int obstack_exit_failure;
11763 + /* Pointer to beginning of object being allocated or to be allocated next.
11764 + Note that this might not be the final address of the object
11765 + because a new chunk might be needed to hold the final size. */
11767 + #define obstack_base(h) ((void *) (h)->object_base)
11769 + /* Size for allocating ordinary chunks. */
11771 + #define obstack_chunk_size(h) ((h)->chunk_size)
11773 + /* Pointer to next byte not yet allocated in current chunk. */
11775 + #define obstack_next_free(h) ((h)->next_free)
11777 + /* Mask specifying low bits that should be clear in address of an object. */
11779 + #define obstack_alignment_mask(h) ((h)->alignment_mask)
11781 + /* To prevent prototype warnings provide complete argument list. */
11782 + #define obstack_init(h) \
11783 + _obstack_begin ((h), 0, 0, \
11784 + (void *(*) (long)) obstack_chunk_alloc, \
11785 + (void (*) (void *)) obstack_chunk_free)
11787 + #define obstack_begin(h, size) \
11788 + _obstack_begin ((h), (size), 0, \
11789 + (void *(*) (long)) obstack_chunk_alloc, \
11790 + (void (*) (void *)) obstack_chunk_free)
11792 + #define obstack_specify_allocation(h, size, alignment, chunkfun, freefun) \
11793 + _obstack_begin ((h), (size), (alignment), \
11794 + (void *(*) (long)) (chunkfun), \
11795 + (void (*) (void *)) (freefun))
11797 + #define obstack_specify_allocation_with_arg(h, size, alignment, chunkfun, freefun, arg) \
11798 + _obstack_begin_1 ((h), (size), (alignment), \
11799 + (void *(*) (void *, long)) (chunkfun), \
11800 + (void (*) (void *, void *)) (freefun), (arg))
11802 + #define obstack_chunkfun(h, newchunkfun) \
11803 + ((h) -> chunkfun = (struct _obstack_chunk *(*)(void *, long)) (newchunkfun))
11805 + #define obstack_freefun(h, newfreefun) \
11806 + ((h) -> freefun = (void (*)(void *, struct _obstack_chunk *)) (newfreefun))
11808 + #define obstack_1grow_fast(h,achar) (*((h)->next_free)++ = (achar))
11810 + #define obstack_blank_fast(h,n) ((h)->next_free += (n))
11812 + #define obstack_memory_used(h) _obstack_memory_used (h)
11814 + #if defined __GNUC__ && defined __STDC__ && __STDC__
11815 + /* NextStep 2.0 cc is really gcc 1.93 but it defines __GNUC__ = 2 and
11816 + does not implement __extension__. But that compiler doesn't define
11817 + __GNUC_MINOR__. */
11818 + # if __GNUC__ < 2 || (__NeXT__ && !__GNUC_MINOR__)
11819 + # define __extension__
11822 + /* For GNU C, if not -traditional,
11823 + we can define these macros to compute all args only once
11824 + without using a global variable.
11825 + Also, we can avoid using the `temp' slot, to make faster code. */
11827 + # define obstack_object_size(OBSTACK) \
11829 + ({ struct obstack const *__o = (OBSTACK); \
11830 + (unsigned) (__o->next_free - __o->object_base); })
11832 + # define obstack_room(OBSTACK) \
11834 + ({ struct obstack const *__o = (OBSTACK); \
11835 + (unsigned) (__o->chunk_limit - __o->next_free); })
11837 + # define obstack_make_room(OBSTACK,length) \
11839 + ({ struct obstack *__o = (OBSTACK); \
11840 + int __len = (length); \
11841 + if (__o->chunk_limit - __o->next_free < __len) \
11842 + _obstack_newchunk (__o, __len); \
11845 + # define obstack_empty_p(OBSTACK) \
11847 + ({ struct obstack const *__o = (OBSTACK); \
11848 + (__o->chunk->prev == 0 \
11849 + && __o->next_free == __PTR_ALIGN ((char *) __o->chunk, \
11850 + __o->chunk->contents, \
11851 + __o->alignment_mask)); })
11853 + # define obstack_grow(OBSTACK,where,length) \
11855 + ({ struct obstack *__o = (OBSTACK); \
11856 + int __len = (length); \
11857 + if (__o->next_free + __len > __o->chunk_limit) \
11858 + _obstack_newchunk (__o, __len); \
11859 + memcpy (__o->next_free, where, __len); \
11860 + __o->next_free += __len; \
11863 + # define obstack_grow0(OBSTACK,where,length) \
11865 + ({ struct obstack *__o = (OBSTACK); \
11866 + int __len = (length); \
11867 + if (__o->next_free + __len + 1 > __o->chunk_limit) \
11868 + _obstack_newchunk (__o, __len + 1); \
11869 + memcpy (__o->next_free, where, __len); \
11870 + __o->next_free += __len; \
11871 + *(__o->next_free)++ = 0; \
11874 + # define obstack_1grow(OBSTACK,datum) \
11876 + ({ struct obstack *__o = (OBSTACK); \
11877 + if (__o->next_free + 1 > __o->chunk_limit) \
11878 + _obstack_newchunk (__o, 1); \
11879 + obstack_1grow_fast (__o, datum); \
11882 + /* These assume that the obstack alignment is good enough for pointers
11883 + or ints, and that the data added so far to the current object
11884 + shares that much alignment. */
11886 + # define obstack_ptr_grow(OBSTACK,datum) \
11888 + ({ struct obstack *__o = (OBSTACK); \
11889 + if (__o->next_free + sizeof (void *) > __o->chunk_limit) \
11890 + _obstack_newchunk (__o, sizeof (void *)); \
11891 + obstack_ptr_grow_fast (__o, datum); }) \
11893 + # define obstack_int_grow(OBSTACK,datum) \
11895 + ({ struct obstack *__o = (OBSTACK); \
11896 + if (__o->next_free + sizeof (int) > __o->chunk_limit) \
11897 + _obstack_newchunk (__o, sizeof (int)); \
11898 + obstack_int_grow_fast (__o, datum); })
11900 + # define obstack_ptr_grow_fast(OBSTACK,aptr) \
11902 + ({ struct obstack *__o1 = (OBSTACK); \
11903 + *(const void **) __o1->next_free = (aptr); \
11904 + __o1->next_free += sizeof (const void *); \
11907 + # define obstack_int_grow_fast(OBSTACK,aint) \
11909 + ({ struct obstack *__o1 = (OBSTACK); \
11910 + *(int *) __o1->next_free = (aint); \
11911 + __o1->next_free += sizeof (int); \
11914 + # define obstack_blank(OBSTACK,length) \
11916 + ({ struct obstack *__o = (OBSTACK); \
11917 + int __len = (length); \
11918 + if (__o->chunk_limit - __o->next_free < __len) \
11919 + _obstack_newchunk (__o, __len); \
11920 + obstack_blank_fast (__o, __len); \
11923 + # define obstack_alloc(OBSTACK,length) \
11925 + ({ struct obstack *__h = (OBSTACK); \
11926 + obstack_blank (__h, (length)); \
11927 + obstack_finish (__h); })
11929 + # define obstack_copy(OBSTACK,where,length) \
11931 + ({ struct obstack *__h = (OBSTACK); \
11932 + obstack_grow (__h, (where), (length)); \
11933 + obstack_finish (__h); })
11935 + # define obstack_copy0(OBSTACK,where,length) \
11937 + ({ struct obstack *__h = (OBSTACK); \
11938 + obstack_grow0 (__h, (where), (length)); \
11939 + obstack_finish (__h); })
11941 + /* The local variable is named __o1 to avoid a name conflict
11942 + when obstack_blank is called. */
11943 + # define obstack_finish(OBSTACK) \
11945 + ({ struct obstack *__o1 = (OBSTACK); \
11946 + void *__value = (void *) __o1->object_base; \
11947 + if (__o1->next_free == __value) \
11948 + __o1->maybe_empty_object = 1; \
11949 + __o1->next_free \
11950 + = __PTR_ALIGN (__o1->object_base, __o1->next_free, \
11951 + __o1->alignment_mask); \
11952 + if (__o1->next_free - (char *)__o1->chunk \
11953 + > __o1->chunk_limit - (char *)__o1->chunk) \
11954 + __o1->next_free = __o1->chunk_limit; \
11955 + __o1->object_base = __o1->next_free; \
11958 + # define obstack_free(OBSTACK, OBJ) \
11960 + ({ struct obstack *__o = (OBSTACK); \
11961 + void *__obj = (OBJ); \
11962 + if (__obj > (void *)__o->chunk && __obj < (void *)__o->chunk_limit) \
11963 + __o->next_free = __o->object_base = (char *)__obj; \
11964 + else (obstack_free) (__o, __obj); })
11966 + #else /* not __GNUC__ or not __STDC__ */
11968 + # define obstack_object_size(h) \
11969 + (unsigned) ((h)->next_free - (h)->object_base)
11971 + # define obstack_room(h) \
11972 + (unsigned) ((h)->chunk_limit - (h)->next_free)
11974 + # define obstack_empty_p(h) \
11975 + ((h)->chunk->prev == 0 \
11976 + && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk, \
11977 + (h)->chunk->contents, \
11978 + (h)->alignment_mask))
11980 + /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
11981 + so that we can avoid having void expressions
11982 + in the arms of the conditional expression.
11983 + Casting the third operand to void was tried before,
11984 + but some compilers won't accept it. */
11986 + # define obstack_make_room(h,length) \
11987 + ( (h)->temp.tempint = (length), \
11988 + (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
11989 + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
11991 + # define obstack_grow(h,where,length) \
11992 + ( (h)->temp.tempint = (length), \
11993 + (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit) \
11994 + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
11995 + memcpy ((h)->next_free, where, (h)->temp.tempint), \
11996 + (h)->next_free += (h)->temp.tempint)
11998 + # define obstack_grow0(h,where,length) \
11999 + ( (h)->temp.tempint = (length), \
12000 + (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit) \
12001 + ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0), \
12002 + memcpy ((h)->next_free, where, (h)->temp.tempint), \
12003 + (h)->next_free += (h)->temp.tempint, \
12004 + *((h)->next_free)++ = 0)
12006 + # define obstack_1grow(h,datum) \
12007 + ( (((h)->next_free + 1 > (h)->chunk_limit) \
12008 + ? (_obstack_newchunk ((h), 1), 0) : 0), \
12009 + obstack_1grow_fast (h, datum))
12011 + # define obstack_ptr_grow(h,datum) \
12012 + ( (((h)->next_free + sizeof (char *) > (h)->chunk_limit) \
12013 + ? (_obstack_newchunk ((h), sizeof (char *)), 0) : 0), \
12014 + obstack_ptr_grow_fast (h, datum))
12016 + # define obstack_int_grow(h,datum) \
12017 + ( (((h)->next_free + sizeof (int) > (h)->chunk_limit) \
12018 + ? (_obstack_newchunk ((h), sizeof (int)), 0) : 0), \
12019 + obstack_int_grow_fast (h, datum))
12021 + # define obstack_ptr_grow_fast(h,aptr) \
12022 + (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
12024 + # define obstack_int_grow_fast(h,aint) \
12025 + (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
12027 + # define obstack_blank(h,length) \
12028 + ( (h)->temp.tempint = (length), \
12029 + (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint) \
12030 + ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0), \
12031 + obstack_blank_fast (h, (h)->temp.tempint))
12033 + # define obstack_alloc(h,length) \
12034 + (obstack_blank ((h), (length)), obstack_finish ((h)))
12036 + # define obstack_copy(h,where,length) \
12037 + (obstack_grow ((h), (where), (length)), obstack_finish ((h)))
12039 + # define obstack_copy0(h,where,length) \
12040 + (obstack_grow0 ((h), (where), (length)), obstack_finish ((h)))
12042 + # define obstack_finish(h) \
12043 + ( ((h)->next_free == (h)->object_base \
12044 + ? (((h)->maybe_empty_object = 1), 0) \
12046 + (h)->temp.tempptr = (h)->object_base, \
12048 + = __PTR_ALIGN ((h)->object_base, (h)->next_free, \
12049 + (h)->alignment_mask), \
12050 + (((h)->next_free - (char *) (h)->chunk \
12051 + > (h)->chunk_limit - (char *) (h)->chunk) \
12052 + ? ((h)->next_free = (h)->chunk_limit) : 0), \
12053 + (h)->object_base = (h)->next_free, \
12054 + (h)->temp.tempptr)
12056 + # define obstack_free(h,obj) \
12057 + ( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk, \
12058 + ((((h)->temp.tempint > 0 \
12059 + && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk)) \
12060 + ? (int) ((h)->next_free = (h)->object_base \
12061 + = (h)->temp.tempint + (char *) (h)->chunk) \
12062 + : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
12064 + #endif /* not __GNUC__ or not __STDC__ */
12066 + #ifdef __cplusplus
12070 + #endif /* obstack.h */