]> Git Repo - binutils.git/blob - gdb/tui/tui.c
67c31147e53c1727b3ad1926f8d47cbffc1c3553
[binutils.git] / gdb / tui / tui.c
1 /*
2    ** tui.c
3    **         General functions for the WDB TUI
4  */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <ctype.h>
9 #include <malloc.h>
10 #ifdef HAVE_TERM_H
11 #include <term.h>
12 #endif
13 #include <signal.h>
14 #include <fcntl.h>
15 #include <termio.h>
16 #include <setjmp.h>
17 #include "defs.h"
18 #include "gdbcmd.h"
19 #include "tui.h"
20 #include "tuiData.h"
21 #include "tuiLayout.h"
22 #include "tuiIO.h"
23 #include "tuiRegs.h"
24 #include "tuiWin.h"
25
26 /* The Solaris header files seem to provide no declaration for this at
27    all when __STDC__ is defined.  This shouldn't conflict with
28    anything.  */
29 extern char *tgoto ();
30
31 /***********************
32 ** Local Definitions
33 ************************/
34 #define FILEDES         2
35 /* Solaris <sys/termios.h> defines CTRL. */
36 #ifndef CTRL
37 #define CTRL(x)         (x & ~0140)
38 #endif
39 #define CHK(val, dft)   (val<=0 ? dft : val)
40
41 #define TOGGLE_USAGE "Usage:toggle breakpoints"
42 #define TUI_TOGGLE_USAGE "Usage:\ttoggle $fregs\n\ttoggle breakpoints"
43
44 /*****************************
45 ** Local static forward decls
46 ******************************/
47 static void _tuiReset (void);
48 static void _toggle_command (char *, int);
49 static void _tui_vToggle_command (va_list);
50 static Opaque _tui_vDo (TuiOpaqueFuncPtr, va_list);
51
52
53
54 /***********************
55 ** Public Functions
56 ************************/
57
58 /*
59    ** tuiInit().
60  */
61 void
62 #ifdef __STDC__
63 tuiInit (char *argv0)
64 #else
65 tuiInit (argv0)
66      char *argv0;
67 #endif
68 {
69   extern void init_page_info ();
70 extern void initialize_tui_files (void);
71
72   initialize_tui_files ();
73   initializeStaticData ();
74   initscr ();
75   refresh ();
76   setTermHeightTo (LINES);
77   setTermWidthTo (COLS);
78   tuiInitWindows ();
79   wrefresh (cmdWin->generic.handle);
80   init_page_info ();
81   /* Don't hook debugger output if doing command-window
82      * the XDB way. However, one thing we do want to do in
83      * XDB style is set up the scrolling region to be
84      * the bottom of the screen (tuiTermUnsetup()).
85    */
86   fputs_unfiltered_hook = NULL;
87   rl_initialize ();             /* need readline initialization to
88                                    * create termcap sequences
89                                  */
90   tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
91
92   return;
93 }                               /* tuiInit */
94
95
96 /*
97    ** tuiInitWindows().
98  */
99 void
100 #ifdef __STDC__
101 tuiInitWindows (void)
102 #else
103 tuiInitWindows ()
104 #endif
105 {
106   TuiWinType type;
107
108   tuiSetLocatorContent (0);
109   showLayout (SRC_COMMAND);
110   keypad (cmdWin->generic.handle, TRUE);
111   echo ();
112   crmode ();
113   nl ();
114   tuiSetWinFocusTo (srcWin);
115
116   return;
117 }                               /* tuiInitWindows */
118
119
120 /*
121    ** tuiCleanUp().
122    **        Kill signal handler and cleanup termination method
123  */
124 void
125 #ifdef __STDC__
126 tuiResetScreen (void)
127 #else
128 tuiResetScreen ()
129 #endif
130 {
131   TuiWinType type = SRC_WIN;
132
133   keypad (cmdWin->generic.handle, FALSE);
134   for (; type < MAX_MAJOR_WINDOWS; type++)
135     {
136       if (m_winPtrNotNull (winList[type]) &&
137           winList[type]->generic.type != UNDEFINED_WIN &&
138           !winList[type]->generic.isVisible)
139         tuiDelWindow (winList[type]);
140     }
141   endwin ();
142   initscr ();
143   refresh ();
144   echo ();
145   crmode ();
146   nl ();
147
148   return;
149 }                               /* tuiResetScreen */
150
151
152 /*
153    ** tuiCleanUp().
154    **        Kill signal handler and cleanup termination method
155  */
156 void
157 #ifdef __STDC__
158 tuiCleanUp (void)
159 #else
160 tuiCleanUp ()
161 #endif
162 {
163   char *buffer;
164   extern char *term_cursor_move;
165
166   signal (SIGINT, SIG_IGN);
167   tuiTermSetup (0);             /* Restore scrolling region to whole screen */
168   keypad (cmdWin->generic.handle, FALSE);
169   freeAllWindows ();
170   endwin ();
171   buffer = tgoto (term_cursor_move, 0, termHeight ());
172   tputs (buffer, 1, putchar);
173   _tuiReset ();
174
175   return;
176 }                               /* tuiCleanUp */
177
178
179 /*
180    ** tuiError().
181  */
182 void
183 #ifdef __STDC__
184 tuiError (
185            char *string,
186            int exitGdb)
187 #else
188 tuiError (string, exitGdb)
189      char *string;
190      int exitGdb;
191 #endif
192 {
193   puts_unfiltered (string);
194   if (exitGdb)
195     {
196       tuiCleanUp ();
197       exit (-1);
198     }
199
200   return;
201 }                               /* tuiError */
202
203
204 /*
205    ** tui_vError()
206    **        tuiError with args in a va_list.
207  */
208 void
209 #ifdef __STDC__
210 tui_vError (
211              va_list args)
212 #else
213 tui_vError (args)
214      va_list args;
215 #endif
216 {
217   char *string;
218   int exitGdb;
219
220   string = va_arg (args, char *);
221   exitGdb = va_arg (args, int);
222
223   tuiError (string, exitGdb);
224
225   return;
226 }                               /* tui_vError */
227
228
229 /*
230    ** tuiFree()
231    **    Wrapper on top of free() to ensure that input address is greater than 0x0
232  */
233 void
234 #ifdef __STDC__
235 tuiFree (
236           char *ptr)
237 #else
238 tuiFree (ptr)
239      char *ptr;
240 #endif
241 {
242   if (ptr != (char *) NULL)
243     {
244       free (ptr);
245     }
246
247   return;
248 }                               /* tuiFree */
249
250
251 /* tuiGetLowDisassemblyAddress().
252    **        Determine what the low address will be to display in the TUI's
253    **        disassembly window.  This may or may not be the same as the
254    **        low address input.
255  */
256 Opaque
257 #ifdef __STDC__
258 tuiGetLowDisassemblyAddress (
259                               Opaque low,
260                               Opaque pc)
261 #else
262 tuiGetLowDisassemblyAddress (low, pc)
263      Opaque low;
264      Opaque pc;
265 #endif
266 {
267   int line;
268   Opaque newLow;
269
270   /*
271      ** Determine where to start the disassembly so that the pc is about in the
272      ** middle of the viewport.
273    */
274   for (line = 0, newLow = pc;
275        (newLow > low &&
276         line < (tuiDefaultWinViewportHeight (DISASSEM_WIN,
277                                              DISASSEM_COMMAND) / 2));)
278     {
279       bfd_byte buffer[4];
280
281       newLow -= sizeof (bfd_getb32 (buffer));
282       line++;
283     }
284
285   return newLow;
286 }                               /* tuiGetLowDisassemblyAddress */
287
288
289 /* tui_vGetLowDisassemblyAddress().
290    **        Determine what the low address will be to display in the TUI's
291    **        disassembly window with args in a va_list.
292  */
293 Opaque
294 #ifdef __STDC__
295 tui_vGetLowDisassemblyAddress (
296                                 va_list args)
297 #else
298 tui_vGetLowDisassemblyAddress (args)
299      va_list args;
300 #endif
301 {
302   int line;
303   Opaque newLow;
304   Opaque low;
305   Opaque pc;
306
307   low = va_arg (args, Opaque);
308   pc = va_arg (args, Opaque);
309
310   return (tuiGetLowDisassemblyAddress (low, pc));
311
312 }                               /* tui_vGetLowDisassemblyAddress */
313
314
315 /*
316    ** tuiDo().
317    **        General purpose function to execute a tui function.  Transitions
318    **        between curses and the are handled here.  This function is called
319    **        by non-tui gdb functions.
320    **
321    **        Errors are caught here.
322    **        If there is no error, the value returned by 'func' is returned.
323    **        If there is an error, then zero is returned.
324    **
325    **       Must not be called with immediate_quit in effect (bad things might
326    **       happen, say we got a signal in the middle of a memcpy to quit_return).
327    **       This is an OK restriction; with very few exceptions immediate_quit can
328    **       be replaced by judicious use of QUIT.
329  */
330 Opaque
331 #ifdef __STDC__
332 tuiDo (
333         TuiOpaqueFuncPtr func,...)
334 #else
335 tuiDo (func, va_alist)
336      TuiOpaqueFuncPtr func;
337      va_dcl
338 #endif
339 {
340   extern int terminal_is_ours;
341
342   Opaque ret = (Opaque) NULL;
343
344   /* It is an error to be tuiDo'ing if we
345      * don't own the terminal.
346    */
347   if (!terminal_is_ours)
348     return ret;
349
350   if (tui_version)
351     {
352       va_list args;
353
354 #ifdef __STDC__
355       va_start (args, func);
356 #else
357       va_start (args);
358 #endif
359       ret = _tui_vDo (func, args);
360       va_end (args);
361     }
362
363   return ret;
364 }                               /* tuiDo */
365
366
367 /*
368    ** tuiDoAndReturnToTop().
369    **        General purpose function to execute a tui function.  Transitions
370    **        between curses and the are handled here.  This function is called
371    **        by non-tui gdb functions who wish to reset gdb to the top level.
372    **        After the tuiDo is performed, a return to the top level occurs.
373    **
374    **        Errors are caught here.
375    **        If there is no error, the value returned by 'func' is returned.
376    **        If there is an error, then zero is returned.
377    **
378    **       Must not be called with immediate_quit in effect (bad things might
379    **       happen, say we got a signal in the middle of a memcpy to quit_return).
380    **       This is an OK restriction; with very few exceptions immediate_quit can
381    **       be replaced by judicious use of QUIT.
382    **
383  */
384 Opaque
385 #ifdef __STDC__
386 tuiDoAndReturnToTop (
387                       TuiOpaqueFuncPtr func,...)
388 #else
389 tuiDoAndReturnToTop (func, va_alist)
390      TuiOpaqueFuncPtr func;
391      va_dcl
392 #endif
393 {
394   extern int terminal_is_ours;
395
396   Opaque ret = (Opaque) NULL;
397
398   /* It is an error to be tuiDo'ing if we
399      * don't own the terminal.
400    */
401   if (!terminal_is_ours)
402     return ret;
403
404   if (tui_version)
405     {
406       va_list args;
407
408 #ifdef __STDC__
409       va_start (args, func);
410 #else
411       va_start (args);
412 #endif
413       ret = _tui_vDo (func, args);
414
415       /* force a return to the top level */
416       return_to_top_level (RETURN_ERROR);
417     }
418
419   return ret;
420 }                               /* tuiDoAndReturnToTop */
421
422
423 void
424 #ifdef __STDC__
425 tui_vSelectSourceSymtab (
426                           va_list args)
427 #else
428 tui_vSelectSourceSymtab (args)
429      va_list args;
430 #endif
431 {
432   struct symtab *s = va_arg (args, struct symtab *);
433
434   select_source_symtab (s);
435   return;
436 }                               /* tui_vSelectSourceSymtab */
437
438
439 /*
440    ** _initialize_tui().
441    **      Function to initialize gdb commands, for tui window manipulation.
442  */
443 void
444 _initialize_tui ()
445 {
446 #if 0
447   if (tui_version)
448     {
449       add_com ("toggle", class_tui, _toggle_command,
450                "Toggle Terminal UI Features\n\
451 Usage: Toggle $fregs\n\
452 \tToggles between single and double precision floating point registers.\n");
453     }
454 #endif
455   char *helpStr;
456
457   if (tui_version)
458     helpStr = "Toggle Specified Features\n\
459 Usage:\ttoggle $fregs\n\ttoggle breakpoints";
460   else
461     helpStr = "Toggle Specified Features\nUsage:toggle breakpoints";
462   add_abbrev_prefix_cmd ("toggle",
463                          class_tui,
464                          _toggle_command,
465                          helpStr,
466                          &togglelist,
467                          "toggle ",
468                          1,
469                          &cmdlist);
470 }                               /* _initialize_tui */
471
472
473 /*
474    ** va_catch_errors().
475    **       General purpose function to execute a function, catching errors.
476    **       If there is no error, the value returned by 'func' is returned.
477    **       If there is error, then zero is returned.
478    **       Note that 'func' must take a variable argument list as well.
479    **
480    **       Must not be called with immediate_quit in effect (bad things might
481    **       happen, say we got a signal in the middle of a memcpy to quit_return).
482    **       This is an OK restriction; with very few exceptions immediate_quit can
483    **       be replaced by judicious use of QUIT.
484  */
485 Opaque
486 #ifdef __STDC__
487 va_catch_errors (
488                   TuiOpaqueFuncPtr func,
489                   va_list args)
490 #else
491 va_catch_errors (func, args)
492      TuiOpaqueFuncPtr func;
493      va_list args;
494 #endif
495 {
496   Opaque ret = (Opaque) NULL;
497
498   /*
499      ** We could have used catch_errors(), but it doesn't handle variable args.
500      ** Also, for the tui, we always want to catch all errors, so we don't
501      ** need to pass a mask, or an error string.
502    */
503   jmp_buf saved_error;
504   jmp_buf saved_quit;
505   jmp_buf tmp_jmp;
506   struct cleanup *saved_cleanup_chain;
507   char *saved_error_pre_print;
508   char *saved_quit_pre_print;
509   extern jmp_buf error_return;
510   extern jmp_buf quit_return;
511
512   saved_cleanup_chain = save_cleanups ();
513   saved_error_pre_print = error_pre_print;
514   saved_quit_pre_print = quit_pre_print;
515
516   memcpy ((char *) saved_error, (char *) error_return, sizeof (jmp_buf));
517   error_pre_print = "";
518   memcpy (saved_quit, quit_return, sizeof (jmp_buf));
519   quit_pre_print = "";
520
521   if (setjmp (tmp_jmp) == 0)
522     {
523       va_list argList = args;
524       memcpy (error_return, tmp_jmp, sizeof (jmp_buf));
525       memcpy (quit_return, tmp_jmp, sizeof (jmp_buf));
526       ret = func (argList);
527     }
528   restore_cleanups (saved_cleanup_chain);
529   memcpy (error_return, saved_error, sizeof (jmp_buf));
530   error_pre_print = saved_error_pre_print;
531   memcpy (quit_return, saved_quit, sizeof (jmp_buf));
532   quit_pre_print = saved_quit_pre_print;
533
534   return ret;
535 }
536
537 /*
538    ** vcatch_errors().
539    **        Catch errors occurring in tui or non tui function, handling
540    **        variable param lists. Note that 'func' must take a variable
541    **        argument list as well.
542  */
543 Opaque
544 #ifdef __STDC__
545 vcatch_errors (
546                 OpaqueFuncPtr func,...)
547 #else
548 vcatch_errors (va_alist)
549      va_dcl
550 /*
551    vcatch_errors(func, va_alist)
552    OpaqueFuncPtr    func;
553    va_dcl
554  */
555 #endif
556 {
557   Opaque ret = (Opaque) NULL;
558   va_list args;
559 #ifdef __STDC__
560   va_start (args, func);
561 /*
562    va_arg(args, OpaqueFuncPtr);
563  */
564 #else
565   OpaqueFuncPtr func;
566
567   va_start (args);
568   func = va_arg (args, OpaqueFuncPtr);
569 #endif
570   ret = va_catch_errors (func, args);
571   va_end (args);
572
573   return ret;
574 }
575
576
577 void
578 #ifdef __STDC__
579 strcat_to_buf (
580                 char *buf,
581                 int buflen,
582                 char *itemToAdd)
583 #else
584 strcat_to_buf (buf, buflen, itemToAdd)
585      char *buf;
586      int buflen;
587      char *itemToAdd;
588 #endif
589 {
590   if (itemToAdd != (char *) NULL && buf != (char *) NULL)
591     {
592       if ((strlen (buf) + strlen (itemToAdd)) <= buflen)
593         strcat (buf, itemToAdd);
594       else
595         strncat (buf, itemToAdd, (buflen - strlen (buf)));
596     }
597
598   return;
599 }                               /* strcat_to_buf */
600
601 /* VARARGS */
602 void
603 #ifdef ANSI_PROTOTYPES
604 strcat_to_buf_with_fmt (
605                          char *buf,
606                          int bufLen,
607                          char *format,...)
608 #else
609 strcat_to_buf_with_fmt (va_alist)
610      va_dcl
611 #endif
612 {
613   char *linebuffer;
614   struct cleanup *old_cleanups;
615   va_list args;
616 #ifdef ANSI_PROTOTYPES
617   va_start (args, format);
618 #else
619   char *buf;
620   int bufLen;
621   char *format;
622
623   va_start (args);
624   buf = va_arg (args, char *);
625   bufLen = va_arg (args, int);
626   format = va_arg (args, char *);
627 #endif
628   vasprintf (&linebuffer, format, args);
629   old_cleanups = make_cleanup (free, linebuffer);
630   strcat_to_buf (buf, bufLen, linebuffer);
631   do_cleanups (old_cleanups);
632   va_end (args);
633 }
634
635
636
637
638
639 /***********************
640 ** Static Functions
641 ************************/
642
643
644 /*
645    ** _tui_vDo().
646    **        General purpose function to execute a tui function.  Transitions
647    **        between curses and the are handled here.  This function is called
648    **        by non-tui gdb functions.
649    **
650    **        Errors are caught here.
651    **        If there is no error, the value returned by 'func' is returned.
652    **        If there is an error, then zero is returned.
653    **
654    **       Must not be called with immediate_quit in effect (bad things might
655    **       happen, say we got a signal in the middle of a memcpy to quit_return).
656    **       This is an OK restriction; with very few exceptions immediate_quit can
657    **       be replaced by judicious use of QUIT.
658  */
659 static Opaque
660 #ifdef __STDC__
661 _tui_vDo (
662            TuiOpaqueFuncPtr func,
663            va_list args)
664 #else
665 _tui_vDo (func, args)
666      TuiOpaqueFuncPtr func;
667      va_list args;
668 #endif
669 {
670   extern int terminal_is_ours;
671
672   Opaque ret = (Opaque) NULL;
673
674   /* It is an error to be tuiDo'ing if we
675      * don't own the terminal.
676    */
677   if (!terminal_is_ours)
678     return ret;
679
680   if (tui_version)
681     {
682       /* If doing command window the "XDB way" (command window
683          * is unmanaged by curses...
684        */
685       /* Set up terminal for TUI */
686       tuiTermSetup (1);
687
688       ret = va_catch_errors (func, args);
689
690       /* Set up terminal for command window */
691       tuiTermUnsetup (1, cmdWin->detail.commandInfo.curch);
692     }
693
694   return ret;
695 }                               /* _tui_vDo */
696
697
698 static void
699 #ifdef __STDC__
700 _toggle_command (
701                   char *arg,
702                   int fromTTY)
703 #else
704 _toggle_command (arg, fromTTY)
705      char *arg;
706      int fromTTY;
707 #endif
708 {
709   printf_filtered ("Specify feature to toggle.\n%s\n",
710                    (tui_version) ? TUI_TOGGLE_USAGE : TOGGLE_USAGE);
711 /*
712    tuiDo((TuiOpaqueFuncPtr)_Toggle_command, arg, fromTTY);
713  */
714 }
715
716 /*
717    ** _tui_vToggle_command().
718  */
719 static void
720 #ifdef __STDC__
721 _tui_vToggle_command (
722                        va_list args)
723 #else
724 _tui_vToggle_command (args)
725      va_list args;
726 #endif
727 {
728   char *arg;
729   int fromTTY;
730
731   arg = va_arg (args, char *);
732
733   if (arg == (char *) NULL)
734     printf_filtered (TOGGLE_USAGE);
735   else
736     {
737       char *ptr = (char *) tuiStrDup (arg);
738       int i;
739
740       for (i = 0; (ptr[i]); i++)
741         ptr[i] = toupper (arg[i]);
742
743       if (subsetCompare (ptr, TUI_FLOAT_REGS_NAME))
744         tuiToggleFloatRegs ();
745 /*        else if (subsetCompare(ptr, "ANOTHER TOGGLE OPTION"))
746    ...
747  */
748       else
749         printf_filtered (TOGGLE_USAGE);
750       tuiFree (ptr);
751     }
752
753   return;
754 }                               /* _tuiToggle_command */
755
756
757 static void
758 #ifdef __STDC__
759 _tuiReset (void)
760 #else
761 _tuiReset ()
762 #endif
763 {
764   struct termio mode;
765
766   /*
767      ** reset the teletype mode bits to a sensible state.
768      ** Copied tset.c
769    */
770 #if ! defined (USG) && defined (TIOCGETC)
771   struct tchars tbuf;
772 #endif /* !USG && TIOCGETC */
773 #ifdef UCB_NTTY
774   struct ltchars ltc;
775
776   if (ldisc == NTTYDISC)
777     {
778       ioctl (FILEDES, TIOCGLTC, &ltc);
779       ltc.t_suspc = CHK (ltc.t_suspc, CTRL ('Z'));
780       ltc.t_dsuspc = CHK (ltc.t_dsuspc, CTRL ('Y'));
781       ltc.t_rprntc = CHK (ltc.t_rprntc, CTRL ('R'));
782       ltc.t_flushc = CHK (ltc.t_flushc, CTRL ('O'));
783       ltc.t_werasc = CHK (ltc.t_werasc, CTRL ('W'));
784       ltc.t_lnextc = CHK (ltc.t_lnextc, CTRL ('V'));
785       ioctl (FILEDES, TIOCSLTC, &ltc);
786     }
787 #endif /* UCB_NTTY */
788 #ifndef USG
789 #ifdef TIOCGETC
790   ioctl (FILEDES, TIOCGETC, &tbuf);
791   tbuf.t_intrc = CHK (tbuf.t_intrc, CTRL ('?'));
792   tbuf.t_quitc = CHK (tbuf.t_quitc, CTRL ('\\'));
793   tbuf.t_startc = CHK (tbuf.t_startc, CTRL ('Q'));
794   tbuf.t_stopc = CHK (tbuf.t_stopc, CTRL ('S'));
795   tbuf.t_eofc = CHK (tbuf.t_eofc, CTRL ('D'));
796   /* brkc is left alone */
797   ioctl (FILEDES, TIOCSETC, &tbuf);
798 #endif /* TIOCGETC */
799   mode.sg_flags &= ~(RAW
800 #ifdef CBREAK
801                      | CBREAK
802 #endif /* CBREAK */
803                      | VTDELAY | ALLDELAY);
804   mode.sg_flags |= XTABS | ECHO | CRMOD | ANYP;
805 #else /*USG */
806   ioctl (FILEDES, TCGETA, &mode);
807   mode.c_cc[VINTR] = CHK (mode.c_cc[VINTR], CTRL ('?'));
808   mode.c_cc[VQUIT] = CHK (mode.c_cc[VQUIT], CTRL ('\\'));
809   mode.c_cc[VEOF] = CHK (mode.c_cc[VEOF], CTRL ('D'));
810
811   mode.c_iflag &= ~(IGNBRK | PARMRK | INPCK | INLCR | IGNCR | IUCLC | IXOFF);
812   mode.c_iflag |= (BRKINT | ISTRIP | ICRNL | IXON);
813   mode.c_oflag &= ~(OLCUC | OCRNL | ONOCR | ONLRET | OFILL | OFDEL |
814                     NLDLY | CRDLY | TABDLY | BSDLY | VTDLY | FFDLY);
815   mode.c_oflag |= (OPOST | ONLCR);
816   mode.c_cflag &= ~(CSIZE | PARODD | CLOCAL);
817 #ifndef hp9000s800
818   mode.c_cflag |= (CS8 | CREAD);
819 #else /*hp9000s800 */
820   mode.c_cflag |= (CS8 | CSTOPB | CREAD);
821 #endif /* hp9000s800 */
822   mode.c_lflag &= ~(XCASE | ECHONL | NOFLSH);
823   mode.c_lflag |= (ISIG | ICANON | ECHO | ECHOK);
824   ioctl (FILEDES, TCSETAW, &mode);
825 #endif /* USG */
826
827   return;
828 }                               /* _tuiReset */
This page took 0.062824 seconds and 2 git commands to generate.