xref: /freebsd/sys/contrib/dev/acpica/common/acgetline.c (revision 313a0c13efa638cf248e35eed49f36ec0a1a7f26)
1*313a0c13SJung-uk Kim /******************************************************************************
2*313a0c13SJung-uk Kim  *
3*313a0c13SJung-uk Kim  * Module Name: acgetline - local line editing
4*313a0c13SJung-uk Kim  *
5*313a0c13SJung-uk Kim  *****************************************************************************/
6*313a0c13SJung-uk Kim 
7*313a0c13SJung-uk Kim /*
8*313a0c13SJung-uk Kim  * Copyright (C) 2000 - 2014, Intel Corp.
9*313a0c13SJung-uk Kim  * All rights reserved.
10*313a0c13SJung-uk Kim  *
11*313a0c13SJung-uk Kim  * Redistribution and use in source and binary forms, with or without
12*313a0c13SJung-uk Kim  * modification, are permitted provided that the following conditions
13*313a0c13SJung-uk Kim  * are met:
14*313a0c13SJung-uk Kim  * 1. Redistributions of source code must retain the above copyright
15*313a0c13SJung-uk Kim  *    notice, this list of conditions, and the following disclaimer,
16*313a0c13SJung-uk Kim  *    without modification.
17*313a0c13SJung-uk Kim  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18*313a0c13SJung-uk Kim  *    substantially similar to the "NO WARRANTY" disclaimer below
19*313a0c13SJung-uk Kim  *    ("Disclaimer") and any redistribution must be conditioned upon
20*313a0c13SJung-uk Kim  *    including a substantially similar Disclaimer requirement for further
21*313a0c13SJung-uk Kim  *    binary redistribution.
22*313a0c13SJung-uk Kim  * 3. Neither the names of the above-listed copyright holders nor the names
23*313a0c13SJung-uk Kim  *    of any contributors may be used to endorse or promote products derived
24*313a0c13SJung-uk Kim  *    from this software without specific prior written permission.
25*313a0c13SJung-uk Kim  *
26*313a0c13SJung-uk Kim  * Alternatively, this software may be distributed under the terms of the
27*313a0c13SJung-uk Kim  * GNU General Public License ("GPL") version 2 as published by the Free
28*313a0c13SJung-uk Kim  * Software Foundation.
29*313a0c13SJung-uk Kim  *
30*313a0c13SJung-uk Kim  * NO WARRANTY
31*313a0c13SJung-uk Kim  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32*313a0c13SJung-uk Kim  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33*313a0c13SJung-uk Kim  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34*313a0c13SJung-uk Kim  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35*313a0c13SJung-uk Kim  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36*313a0c13SJung-uk Kim  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37*313a0c13SJung-uk Kim  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38*313a0c13SJung-uk Kim  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39*313a0c13SJung-uk Kim  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40*313a0c13SJung-uk Kim  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41*313a0c13SJung-uk Kim  * POSSIBILITY OF SUCH DAMAGES.
42*313a0c13SJung-uk Kim  */
43*313a0c13SJung-uk Kim 
44*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/acpi.h>
45*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/accommon.h>
46*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/amlcode.h>
47*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/acparser.h>
48*313a0c13SJung-uk Kim #include <contrib/dev/acpica/include/acdebug.h>
49*313a0c13SJung-uk Kim 
50*313a0c13SJung-uk Kim #include <stdio.h>
51*313a0c13SJung-uk Kim 
52*313a0c13SJung-uk Kim /*
53*313a0c13SJung-uk Kim  * This is an os-independent implementation of line-editing services needed
54*313a0c13SJung-uk Kim  * by the AcpiExec utility. It uses getchar() and putchar() and the existing
55*313a0c13SJung-uk Kim  * history support provided by the AML debugger. It assumes that the terminal
56*313a0c13SJung-uk Kim  * is in the correct line-editing mode such as raw and noecho. The OSL
57*313a0c13SJung-uk Kim  * interface AcpiOsInitialize should do this. AcpiOsTerminate should put the
58*313a0c13SJung-uk Kim  * terminal back into the original mode.
59*313a0c13SJung-uk Kim  */
60*313a0c13SJung-uk Kim #define _COMPONENT          ACPI_OS_SERVICES
61*313a0c13SJung-uk Kim         ACPI_MODULE_NAME    ("acgetline")
62*313a0c13SJung-uk Kim 
63*313a0c13SJung-uk Kim 
64*313a0c13SJung-uk Kim /* Local prototypes */
65*313a0c13SJung-uk Kim 
66*313a0c13SJung-uk Kim static void
67*313a0c13SJung-uk Kim AcpiAcClearLine (
68*313a0c13SJung-uk Kim     UINT32                  EndOfLine,
69*313a0c13SJung-uk Kim     UINT32                  CursorPosition);
70*313a0c13SJung-uk Kim 
71*313a0c13SJung-uk Kim /* Various ASCII constants */
72*313a0c13SJung-uk Kim 
73*313a0c13SJung-uk Kim #define _ASCII_NUL                  0
74*313a0c13SJung-uk Kim #define _ASCII_BACKSPACE            0x08
75*313a0c13SJung-uk Kim #define _ASCII_TAB                  0x09
76*313a0c13SJung-uk Kim #define _ASCII_ESCAPE               0x1B
77*313a0c13SJung-uk Kim #define _ASCII_SPACE                0x20
78*313a0c13SJung-uk Kim #define _ASCII_LEFT_BRACKET         0x5B
79*313a0c13SJung-uk Kim #define _ASCII_DEL                  0x7F
80*313a0c13SJung-uk Kim #define _ASCII_UP_ARROW             'A'
81*313a0c13SJung-uk Kim #define _ASCII_DOWN_ARROW           'B'
82*313a0c13SJung-uk Kim #define _ASCII_RIGHT_ARROW          'C'
83*313a0c13SJung-uk Kim #define _ASCII_LEFT_ARROW           'D'
84*313a0c13SJung-uk Kim #define _ASCII_NEWLINE              '\n'
85*313a0c13SJung-uk Kim 
86*313a0c13SJung-uk Kim extern UINT32               AcpiGbl_NextCmdNum;
87*313a0c13SJung-uk Kim 
88*313a0c13SJung-uk Kim /* Erase a single character on the input command line */
89*313a0c13SJung-uk Kim 
90*313a0c13SJung-uk Kim #define ACPI_CLEAR_CHAR() \
91*313a0c13SJung-uk Kim     putchar (_ASCII_BACKSPACE); \
92*313a0c13SJung-uk Kim     putchar (_ASCII_SPACE); \
93*313a0c13SJung-uk Kim     putchar (_ASCII_BACKSPACE);
94*313a0c13SJung-uk Kim 
95*313a0c13SJung-uk Kim /* Backup cursor by Count positions */
96*313a0c13SJung-uk Kim 
97*313a0c13SJung-uk Kim #define ACPI_BACKUP_CURSOR(i, Count) \
98*313a0c13SJung-uk Kim     for (i = 0; i < (Count); i++) \
99*313a0c13SJung-uk Kim         {putchar (_ASCII_BACKSPACE);}
100*313a0c13SJung-uk Kim 
101*313a0c13SJung-uk Kim 
102*313a0c13SJung-uk Kim /******************************************************************************
103*313a0c13SJung-uk Kim  *
104*313a0c13SJung-uk Kim  * FUNCTION:    AcpiAcClearLine
105*313a0c13SJung-uk Kim  *
106*313a0c13SJung-uk Kim  * PARAMETERS:  EndOfLine           - Current end-of-line index
107*313a0c13SJung-uk Kim  *              CursorPosition      - Current cursor position within line
108*313a0c13SJung-uk Kim  *
109*313a0c13SJung-uk Kim  * RETURN:      None
110*313a0c13SJung-uk Kim  *
111*313a0c13SJung-uk Kim  * DESCRIPTION: Clear the entire command line the hard way, but probably the
112*313a0c13SJung-uk Kim  *              most portable.
113*313a0c13SJung-uk Kim  *
114*313a0c13SJung-uk Kim  *****************************************************************************/
115*313a0c13SJung-uk Kim 
116*313a0c13SJung-uk Kim static void
117*313a0c13SJung-uk Kim AcpiAcClearLine (
118*313a0c13SJung-uk Kim     UINT32                  EndOfLine,
119*313a0c13SJung-uk Kim     UINT32                  CursorPosition)
120*313a0c13SJung-uk Kim {
121*313a0c13SJung-uk Kim     UINT32                  i;
122*313a0c13SJung-uk Kim 
123*313a0c13SJung-uk Kim 
124*313a0c13SJung-uk Kim     if (CursorPosition < EndOfLine)
125*313a0c13SJung-uk Kim     {
126*313a0c13SJung-uk Kim         /* Clear line from current position to end of line */
127*313a0c13SJung-uk Kim 
128*313a0c13SJung-uk Kim         for (i = 0; i < (EndOfLine - CursorPosition); i++)
129*313a0c13SJung-uk Kim         {
130*313a0c13SJung-uk Kim             putchar (' ');
131*313a0c13SJung-uk Kim         }
132*313a0c13SJung-uk Kim     }
133*313a0c13SJung-uk Kim 
134*313a0c13SJung-uk Kim     /* Clear the entire line */
135*313a0c13SJung-uk Kim 
136*313a0c13SJung-uk Kim     for (; EndOfLine > 0; EndOfLine--)
137*313a0c13SJung-uk Kim     {
138*313a0c13SJung-uk Kim         ACPI_CLEAR_CHAR ();
139*313a0c13SJung-uk Kim     }
140*313a0c13SJung-uk Kim }
141*313a0c13SJung-uk Kim 
142*313a0c13SJung-uk Kim 
143*313a0c13SJung-uk Kim /******************************************************************************
144*313a0c13SJung-uk Kim  *
145*313a0c13SJung-uk Kim  * FUNCTION:    AcpiOsGetLine
146*313a0c13SJung-uk Kim  *
147*313a0c13SJung-uk Kim  * PARAMETERS:  Buffer              - Where to return the command line
148*313a0c13SJung-uk Kim  *              BufferLength        - Maximum length of Buffer
149*313a0c13SJung-uk Kim  *              BytesRead           - Where the actual byte count is returned
150*313a0c13SJung-uk Kim  *
151*313a0c13SJung-uk Kim  * RETURN:      Status and actual bytes read
152*313a0c13SJung-uk Kim  *
153*313a0c13SJung-uk Kim  * DESCRIPTION: Get the next input line from the terminal. NOTE: terminal
154*313a0c13SJung-uk Kim  *              is expected to be in a mode that supports line-editing (raw,
155*313a0c13SJung-uk Kim  *              noecho). This function is intended to be very portable. Also,
156*313a0c13SJung-uk Kim  *              it uses the history support implemented in the AML debugger.
157*313a0c13SJung-uk Kim  *
158*313a0c13SJung-uk Kim  *****************************************************************************/
159*313a0c13SJung-uk Kim 
160*313a0c13SJung-uk Kim ACPI_STATUS
161*313a0c13SJung-uk Kim AcpiOsGetLine (
162*313a0c13SJung-uk Kim     char                    *Buffer,
163*313a0c13SJung-uk Kim     UINT32                  BufferLength,
164*313a0c13SJung-uk Kim     UINT32                  *BytesRead)
165*313a0c13SJung-uk Kim {
166*313a0c13SJung-uk Kim     char                    *NextCommand;
167*313a0c13SJung-uk Kim     UINT32                  MaxCommandIndex = AcpiGbl_NextCmdNum - 1;
168*313a0c13SJung-uk Kim     UINT32                  CurrentCommandIndex = MaxCommandIndex;
169*313a0c13SJung-uk Kim     UINT32                  PreviousCommandIndex = MaxCommandIndex;
170*313a0c13SJung-uk Kim     int                     InputChar;
171*313a0c13SJung-uk Kim     UINT32                  CursorPosition = 0;
172*313a0c13SJung-uk Kim     UINT32                  EndOfLine = 0;
173*313a0c13SJung-uk Kim     UINT32                  i;
174*313a0c13SJung-uk Kim 
175*313a0c13SJung-uk Kim 
176*313a0c13SJung-uk Kim     /* Always clear the line buffer before we read a new line */
177*313a0c13SJung-uk Kim 
178*313a0c13SJung-uk Kim     memset (Buffer, 0, BufferLength);
179*313a0c13SJung-uk Kim 
180*313a0c13SJung-uk Kim     /*
181*313a0c13SJung-uk Kim      * This loop gets one character at a time (except for esc sequences)
182*313a0c13SJung-uk Kim      * until a newline or error is detected.
183*313a0c13SJung-uk Kim      *
184*313a0c13SJung-uk Kim      * Note: Don't attempt to write terminal control ESC sequences, even
185*313a0c13SJung-uk Kim      * though it makes certain things more difficult.
186*313a0c13SJung-uk Kim      */
187*313a0c13SJung-uk Kim     while (1)
188*313a0c13SJung-uk Kim     {
189*313a0c13SJung-uk Kim         if (EndOfLine >= (BufferLength - 1))
190*313a0c13SJung-uk Kim         {
191*313a0c13SJung-uk Kim             return (AE_BUFFER_OVERFLOW);
192*313a0c13SJung-uk Kim         }
193*313a0c13SJung-uk Kim 
194*313a0c13SJung-uk Kim         InputChar = getchar ();
195*313a0c13SJung-uk Kim         switch (InputChar)
196*313a0c13SJung-uk Kim         {
197*313a0c13SJung-uk Kim         default: /* This is the normal character case */
198*313a0c13SJung-uk Kim 
199*313a0c13SJung-uk Kim             /* Echo the character (at EOL) and copy it to the line buffer */
200*313a0c13SJung-uk Kim 
201*313a0c13SJung-uk Kim             if (EndOfLine == CursorPosition)
202*313a0c13SJung-uk Kim             {
203*313a0c13SJung-uk Kim                 putchar (InputChar);
204*313a0c13SJung-uk Kim                 Buffer[EndOfLine] = (char) InputChar;
205*313a0c13SJung-uk Kim 
206*313a0c13SJung-uk Kim                 EndOfLine++;
207*313a0c13SJung-uk Kim                 CursorPosition++;
208*313a0c13SJung-uk Kim                 Buffer[EndOfLine] = 0;
209*313a0c13SJung-uk Kim                 continue;
210*313a0c13SJung-uk Kim             }
211*313a0c13SJung-uk Kim 
212*313a0c13SJung-uk Kim             /* Insert character into the middle of the buffer */
213*313a0c13SJung-uk Kim 
214*313a0c13SJung-uk Kim             memmove (&Buffer[CursorPosition + 1], &Buffer[CursorPosition],
215*313a0c13SJung-uk Kim                 (EndOfLine - CursorPosition + 1));
216*313a0c13SJung-uk Kim 
217*313a0c13SJung-uk Kim             Buffer [CursorPosition] = (char) InputChar;
218*313a0c13SJung-uk Kim             Buffer [EndOfLine + 1] = 0;
219*313a0c13SJung-uk Kim 
220*313a0c13SJung-uk Kim             /* Display the new part of line starting at the new character */
221*313a0c13SJung-uk Kim 
222*313a0c13SJung-uk Kim             fprintf (stdout, "%s", &Buffer[CursorPosition]);
223*313a0c13SJung-uk Kim 
224*313a0c13SJung-uk Kim             /* Restore cursor */
225*313a0c13SJung-uk Kim 
226*313a0c13SJung-uk Kim             ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition);
227*313a0c13SJung-uk Kim             CursorPosition++;
228*313a0c13SJung-uk Kim             EndOfLine++;
229*313a0c13SJung-uk Kim             continue;
230*313a0c13SJung-uk Kim 
231*313a0c13SJung-uk Kim         case _ASCII_DEL: /* Backspace key */
232*313a0c13SJung-uk Kim 
233*313a0c13SJung-uk Kim             if (!EndOfLine) /* Any characters on the command line? */
234*313a0c13SJung-uk Kim             {
235*313a0c13SJung-uk Kim                 continue;
236*313a0c13SJung-uk Kim             }
237*313a0c13SJung-uk Kim 
238*313a0c13SJung-uk Kim             if (EndOfLine == CursorPosition) /* Erase the final character */
239*313a0c13SJung-uk Kim             {
240*313a0c13SJung-uk Kim                 ACPI_CLEAR_CHAR ();
241*313a0c13SJung-uk Kim                 EndOfLine--;
242*313a0c13SJung-uk Kim                 CursorPosition--;
243*313a0c13SJung-uk Kim                 continue;
244*313a0c13SJung-uk Kim             }
245*313a0c13SJung-uk Kim 
246*313a0c13SJung-uk Kim             if (!CursorPosition) /* Do not backup beyond start of line */
247*313a0c13SJung-uk Kim             {
248*313a0c13SJung-uk Kim                 continue;
249*313a0c13SJung-uk Kim             }
250*313a0c13SJung-uk Kim 
251*313a0c13SJung-uk Kim             /* Remove the character from the line */
252*313a0c13SJung-uk Kim 
253*313a0c13SJung-uk Kim             memmove (&Buffer[CursorPosition - 1], &Buffer[CursorPosition],
254*313a0c13SJung-uk Kim                 (EndOfLine - CursorPosition + 1));
255*313a0c13SJung-uk Kim 
256*313a0c13SJung-uk Kim             /* Display the new part of line starting at the new character */
257*313a0c13SJung-uk Kim 
258*313a0c13SJung-uk Kim             putchar (_ASCII_BACKSPACE);
259*313a0c13SJung-uk Kim             fprintf (stdout, "%s ", &Buffer[CursorPosition - 1]);
260*313a0c13SJung-uk Kim 
261*313a0c13SJung-uk Kim             /* Restore cursor */
262*313a0c13SJung-uk Kim 
263*313a0c13SJung-uk Kim             ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition + 1);
264*313a0c13SJung-uk Kim             EndOfLine--;
265*313a0c13SJung-uk Kim             if (CursorPosition > 0)
266*313a0c13SJung-uk Kim             {
267*313a0c13SJung-uk Kim                 CursorPosition--;
268*313a0c13SJung-uk Kim             }
269*313a0c13SJung-uk Kim             continue;
270*313a0c13SJung-uk Kim 
271*313a0c13SJung-uk Kim         case _ASCII_NEWLINE: /* Normal exit case at end of command line */
272*313a0c13SJung-uk Kim         case _ASCII_NUL:
273*313a0c13SJung-uk Kim 
274*313a0c13SJung-uk Kim             /* Return the number of bytes in the command line string */
275*313a0c13SJung-uk Kim 
276*313a0c13SJung-uk Kim             if (BytesRead)
277*313a0c13SJung-uk Kim             {
278*313a0c13SJung-uk Kim                 *BytesRead = EndOfLine;
279*313a0c13SJung-uk Kim             }
280*313a0c13SJung-uk Kim 
281*313a0c13SJung-uk Kim             /* Echo, terminate string buffer, and exit */
282*313a0c13SJung-uk Kim 
283*313a0c13SJung-uk Kim             putchar (InputChar);
284*313a0c13SJung-uk Kim             Buffer[EndOfLine] = 0;
285*313a0c13SJung-uk Kim             return (AE_OK);
286*313a0c13SJung-uk Kim 
287*313a0c13SJung-uk Kim         case _ASCII_TAB:
288*313a0c13SJung-uk Kim 
289*313a0c13SJung-uk Kim             /* Ignore */
290*313a0c13SJung-uk Kim 
291*313a0c13SJung-uk Kim             continue;
292*313a0c13SJung-uk Kim 
293*313a0c13SJung-uk Kim         case EOF:
294*313a0c13SJung-uk Kim 
295*313a0c13SJung-uk Kim             return (AE_ERROR);
296*313a0c13SJung-uk Kim 
297*313a0c13SJung-uk Kim         case _ASCII_ESCAPE:
298*313a0c13SJung-uk Kim 
299*313a0c13SJung-uk Kim             /* Check for escape sequences of the form "ESC[x" */
300*313a0c13SJung-uk Kim 
301*313a0c13SJung-uk Kim             InputChar = getchar ();
302*313a0c13SJung-uk Kim             if (InputChar != _ASCII_LEFT_BRACKET)
303*313a0c13SJung-uk Kim             {
304*313a0c13SJung-uk Kim                 continue; /* Ignore this ESC, does not have the '[' */
305*313a0c13SJung-uk Kim             }
306*313a0c13SJung-uk Kim 
307*313a0c13SJung-uk Kim             /* Get the code following the ESC [ */
308*313a0c13SJung-uk Kim 
309*313a0c13SJung-uk Kim             InputChar = getchar (); /* Backup one character */
310*313a0c13SJung-uk Kim             switch (InputChar)
311*313a0c13SJung-uk Kim             {
312*313a0c13SJung-uk Kim             case _ASCII_LEFT_ARROW:
313*313a0c13SJung-uk Kim 
314*313a0c13SJung-uk Kim                 if (CursorPosition > 0)
315*313a0c13SJung-uk Kim                 {
316*313a0c13SJung-uk Kim                     putchar (_ASCII_BACKSPACE);
317*313a0c13SJung-uk Kim                     CursorPosition--;
318*313a0c13SJung-uk Kim                 }
319*313a0c13SJung-uk Kim                 continue;
320*313a0c13SJung-uk Kim 
321*313a0c13SJung-uk Kim             case _ASCII_RIGHT_ARROW:
322*313a0c13SJung-uk Kim                 /*
323*313a0c13SJung-uk Kim                  * Move one character forward. Do this without sending
324*313a0c13SJung-uk Kim                  * ESC sequence to the terminal for max portability.
325*313a0c13SJung-uk Kim                  */
326*313a0c13SJung-uk Kim                 if (CursorPosition < EndOfLine)
327*313a0c13SJung-uk Kim                 {
328*313a0c13SJung-uk Kim                     /* Backup to start of line and print the entire line */
329*313a0c13SJung-uk Kim 
330*313a0c13SJung-uk Kim                     ACPI_BACKUP_CURSOR (i, CursorPosition);
331*313a0c13SJung-uk Kim                     fprintf (stdout, "%s", Buffer);
332*313a0c13SJung-uk Kim 
333*313a0c13SJung-uk Kim                     /* Backup to where the cursor should be */
334*313a0c13SJung-uk Kim 
335*313a0c13SJung-uk Kim                     CursorPosition++;
336*313a0c13SJung-uk Kim                     ACPI_BACKUP_CURSOR (i, EndOfLine - CursorPosition);
337*313a0c13SJung-uk Kim                 }
338*313a0c13SJung-uk Kim                 continue;
339*313a0c13SJung-uk Kim 
340*313a0c13SJung-uk Kim             case _ASCII_UP_ARROW:
341*313a0c13SJung-uk Kim 
342*313a0c13SJung-uk Kim                 /* If no commands available or at start of history list, ignore */
343*313a0c13SJung-uk Kim 
344*313a0c13SJung-uk Kim                 if (!CurrentCommandIndex)
345*313a0c13SJung-uk Kim                 {
346*313a0c13SJung-uk Kim                     continue;
347*313a0c13SJung-uk Kim                 }
348*313a0c13SJung-uk Kim 
349*313a0c13SJung-uk Kim                 /* Manage our up/down progress */
350*313a0c13SJung-uk Kim 
351*313a0c13SJung-uk Kim                 if (CurrentCommandIndex > PreviousCommandIndex)
352*313a0c13SJung-uk Kim                 {
353*313a0c13SJung-uk Kim                     CurrentCommandIndex = PreviousCommandIndex;
354*313a0c13SJung-uk Kim                 }
355*313a0c13SJung-uk Kim 
356*313a0c13SJung-uk Kim                 /* Get the historical command from the debugger */
357*313a0c13SJung-uk Kim 
358*313a0c13SJung-uk Kim                 NextCommand = AcpiDbGetHistoryByIndex (CurrentCommandIndex);
359*313a0c13SJung-uk Kim                 if (!NextCommand)
360*313a0c13SJung-uk Kim                 {
361*313a0c13SJung-uk Kim                     return (AE_ERROR);
362*313a0c13SJung-uk Kim                 }
363*313a0c13SJung-uk Kim 
364*313a0c13SJung-uk Kim                 /* Make this the active command and echo it */
365*313a0c13SJung-uk Kim 
366*313a0c13SJung-uk Kim                 AcpiAcClearLine (EndOfLine, CursorPosition);
367*313a0c13SJung-uk Kim                 strcpy (Buffer, NextCommand);
368*313a0c13SJung-uk Kim                 fprintf (stdout, "%s", Buffer);
369*313a0c13SJung-uk Kim                 EndOfLine = CursorPosition = strlen (Buffer);
370*313a0c13SJung-uk Kim 
371*313a0c13SJung-uk Kim                 PreviousCommandIndex = CurrentCommandIndex;
372*313a0c13SJung-uk Kim                 CurrentCommandIndex--;
373*313a0c13SJung-uk Kim                 continue;
374*313a0c13SJung-uk Kim 
375*313a0c13SJung-uk Kim             case _ASCII_DOWN_ARROW:
376*313a0c13SJung-uk Kim 
377*313a0c13SJung-uk Kim                 if (!MaxCommandIndex) /* Any commands available? */
378*313a0c13SJung-uk Kim                 {
379*313a0c13SJung-uk Kim                     continue;
380*313a0c13SJung-uk Kim                 }
381*313a0c13SJung-uk Kim 
382*313a0c13SJung-uk Kim                 /* Manage our up/down progress */
383*313a0c13SJung-uk Kim 
384*313a0c13SJung-uk Kim                 if (CurrentCommandIndex < PreviousCommandIndex)
385*313a0c13SJung-uk Kim                 {
386*313a0c13SJung-uk Kim                     CurrentCommandIndex = PreviousCommandIndex;
387*313a0c13SJung-uk Kim                 }
388*313a0c13SJung-uk Kim 
389*313a0c13SJung-uk Kim                 /* If we are the end of the history list, output a clear new line */
390*313a0c13SJung-uk Kim 
391*313a0c13SJung-uk Kim                 if ((CurrentCommandIndex + 1) > MaxCommandIndex)
392*313a0c13SJung-uk Kim                 {
393*313a0c13SJung-uk Kim                     AcpiAcClearLine (EndOfLine, CursorPosition);
394*313a0c13SJung-uk Kim                     EndOfLine = CursorPosition = 0;
395*313a0c13SJung-uk Kim                     PreviousCommandIndex = CurrentCommandIndex;
396*313a0c13SJung-uk Kim                     continue;
397*313a0c13SJung-uk Kim                 }
398*313a0c13SJung-uk Kim 
399*313a0c13SJung-uk Kim                 PreviousCommandIndex = CurrentCommandIndex;
400*313a0c13SJung-uk Kim                 CurrentCommandIndex++;
401*313a0c13SJung-uk Kim 
402*313a0c13SJung-uk Kim                  /* Get the historical command from the debugger */
403*313a0c13SJung-uk Kim 
404*313a0c13SJung-uk Kim                 NextCommand = AcpiDbGetHistoryByIndex (CurrentCommandIndex);
405*313a0c13SJung-uk Kim                 if (!NextCommand)
406*313a0c13SJung-uk Kim                 {
407*313a0c13SJung-uk Kim                     return (AE_ERROR);
408*313a0c13SJung-uk Kim                 }
409*313a0c13SJung-uk Kim 
410*313a0c13SJung-uk Kim                 /* Make this the active command and echo it */
411*313a0c13SJung-uk Kim 
412*313a0c13SJung-uk Kim                 AcpiAcClearLine (EndOfLine, CursorPosition);
413*313a0c13SJung-uk Kim                 strcpy (Buffer, NextCommand);
414*313a0c13SJung-uk Kim                 fprintf (stdout, "%s", Buffer);
415*313a0c13SJung-uk Kim                 EndOfLine = CursorPosition = strlen (Buffer);
416*313a0c13SJung-uk Kim                 continue;
417*313a0c13SJung-uk Kim 
418*313a0c13SJung-uk Kim             case 0x31:
419*313a0c13SJung-uk Kim             case 0x32:
420*313a0c13SJung-uk Kim             case 0x33:
421*313a0c13SJung-uk Kim             case 0x34:
422*313a0c13SJung-uk Kim             case 0x35:
423*313a0c13SJung-uk Kim             case 0x36:
424*313a0c13SJung-uk Kim                 /*
425*313a0c13SJung-uk Kim                  * Ignore the various keys like insert/delete/home/end, etc.
426*313a0c13SJung-uk Kim                  * But we must eat the final character of the ESC sequence.
427*313a0c13SJung-uk Kim                  */
428*313a0c13SJung-uk Kim                 InputChar = getchar ();
429*313a0c13SJung-uk Kim                 continue;
430*313a0c13SJung-uk Kim 
431*313a0c13SJung-uk Kim             default:
432*313a0c13SJung-uk Kim 
433*313a0c13SJung-uk Kim                 /* Ignore random escape sequences that we don't care about */
434*313a0c13SJung-uk Kim 
435*313a0c13SJung-uk Kim                 continue;
436*313a0c13SJung-uk Kim             }
437*313a0c13SJung-uk Kim             continue;
438*313a0c13SJung-uk Kim         }
439*313a0c13SJung-uk Kim     }
440*313a0c13SJung-uk Kim }
441