~ubuntu-branches/debian/sid/grub2/sid-200907171834

1.1.2 by Otavio Salvador
Import upstream version 1.92
1
/*
2
 *  GRUB  --  GRand Unified Bootloader
1.1.8 by Robert Millan
Import upstream version 1.95+20080128
3
 *  Copyright (C) 2005,2006,2007,2008  Free Software Foundation, Inc.
1.1.2 by Otavio Salvador
Import upstream version 1.92
4
 *
1.1.7 by Robert Millan
Import upstream version 1.95+20071101
5
 *  GRUB is free software: you can redistribute it and/or modify
1.1.2 by Otavio Salvador
Import upstream version 1.92
6
 *  it under the terms of the GNU General Public License as published by
1.1.7 by Robert Millan
Import upstream version 1.95+20071101
7
 *  the Free Software Foundation, either version 3 of the License, or
1.1.2 by Otavio Salvador
Import upstream version 1.92
8
 *  (at your option) any later version.
9
 *
1.1.7 by Robert Millan
Import upstream version 1.95+20071101
10
 *  GRUB is distributed in the hope that it will be useful,
1.1.2 by Otavio Salvador
Import upstream version 1.92
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
1.1.7 by Robert Millan
Import upstream version 1.95+20071101
16
 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
1.1.2 by Otavio Salvador
Import upstream version 1.92
17
 */
18
19
#include <grub/normal.h>
20
#include <grub/term.h>
21
#include <grub/misc.h>
22
#include <grub/mm.h>
23
#include <grub/loader.h>
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
24
#include <grub/script.h>
1.1.2 by Otavio Salvador
Import upstream version 1.92
25
26
enum update_mode
27
  {
28
    NO_LINE,
29
    SINGLE_LINE,
30
    ALL_LINES
31
  };
32
33
struct line
34
{
35
  /* The line buffer.  */
36
  char *buf;
37
  /* The length of the line.  */
38
  int len;
39
  /* The maximum length of the line.  */
40
  int max_len;
41
};
42
43
struct screen
44
{
45
  /* The array of lines.  */
46
  struct line *lines;
47
  /* The number of lines.  */
48
  int num_lines;
49
  /* The current column.  */
50
  int column;
51
  /* The real column.  */
52
  int real_column;
53
  /* The current line.  */
54
  int line;
55
  /* The X coordinate.  */
56
  int x;
57
  /* The Y coordinate.  */
58
  int y;
59
  /* The kill buffer.  */
60
  char *killed_text;
61
  /* The flag of a completion window.  */
62
  int completion_shown;
63
};
64
65
/* Used for storing completion items temporarily.  */
66
static struct line completion_buffer;
67
68
/* Initialize a line.  */
69
static int
70
init_line (struct line *linep)
71
{
72
  linep->len = 0;
73
  linep->max_len = 80; /* XXX */
74
  linep->buf = grub_malloc (linep->max_len);
75
  if (! linep->buf)
76
    return 0;
77
78
  return 1;
79
}
80
81
/* Allocate extra space if necessary.  */
82
static int
83
ensure_space (struct line *linep, int extra)
84
{
85
  if (linep->max_len < linep->len + extra)
86
    {
87
      linep->max_len = linep->len + extra + 80; /* XXX */
88
      linep->buf = grub_realloc (linep->buf, linep->max_len + 1);
89
      if (! linep->buf)
90
	return 0;
91
    }
92
93
  return 1;
94
}
95
96
/* Return the number of lines occupied by this line on the screen.  */
97
static int
98
get_logical_num_lines (struct line *linep)
99
{
100
  return (linep->len / GRUB_TERM_ENTRY_WIDTH) + 1;
101
}
102
103
/* Print a line.  */
104
static void
105
print_line (struct line *linep, int offset, int start, int y)
106
{
107
  int i;
108
  char *p;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
109
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
110
  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + start + 1,
111
	       y + GRUB_TERM_FIRST_ENTRY_Y);
112
113
  for (p = linep->buf + offset + start, i = start;
114
       i < GRUB_TERM_ENTRY_WIDTH && offset + i < linep->len;
115
       p++, i++)
116
    grub_putchar (*p);
117
118
  for (; i < GRUB_TERM_ENTRY_WIDTH; i++)
119
    grub_putchar (' ');
120
121
  if (linep->len >= offset + GRUB_TERM_ENTRY_WIDTH)
122
    grub_putchar ('\\');
123
  else
124
    grub_putchar (' ');
125
}
126
127
/* Print an empty line.  */
128
static void
129
print_empty_line (int y)
130
{
131
  int i;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
132
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
133
  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1,
134
	       y + GRUB_TERM_FIRST_ENTRY_Y);
135
136
  for (i = 0; i < GRUB_TERM_ENTRY_WIDTH + 1; i++)
137
    grub_putchar (' ');
138
}
139
140
/* Print an up arrow.  */
141
static void
142
print_up (int flag)
143
{
144
  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
145
	       GRUB_TERM_FIRST_ENTRY_Y);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
146
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
147
  if (flag)
148
    grub_putcode (GRUB_TERM_DISP_UP);
149
  else
150
    grub_putchar (' ');
151
}
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
152
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
153
/* Print a down arrow.  */
154
static void
155
print_down (int flag)
156
{
157
  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_BORDER_WIDTH,
158
	       GRUB_TERM_TOP_BORDER_Y + GRUB_TERM_NUM_ENTRIES);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
159
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
160
  if (flag)
161
    grub_putcode (GRUB_TERM_DISP_DOWN);
162
  else
163
    grub_putchar (' ');
164
}
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
165
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
166
/* Draw the lines of the screen SCREEN.  */
167
static void
168
update_screen (struct screen *screen, int region_start, int region_column,
169
	       int up, int down, enum update_mode mode)
170
{
171
  int up_flag = 0;
172
  int down_flag = 0;
173
  int y;
174
  int i;
175
  struct line *linep;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
176
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
177
  /* Check if scrolling is necessary.  */
178
  if (screen->y < 0 || screen->y >= GRUB_TERM_NUM_ENTRIES)
179
    {
180
      if (screen->y < 0)
181
	screen->y = 0;
182
      else
183
	screen->y = GRUB_TERM_NUM_ENTRIES - 1;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
184
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
185
      region_start = 0;
186
      region_column = 0;
187
      up = 1;
188
      down = 1;
189
      mode = ALL_LINES;
190
    }
191
192
  if (mode != NO_LINE)
193
    {
194
      /* Draw lines. This code is tricky, because this must calculate logical
195
	 positions.  */
196
      y = screen->y - screen->column / GRUB_TERM_ENTRY_WIDTH;
197
      i = screen->line;
198
      linep = screen->lines + i;
199
      while (y > 0)
200
	{
201
	   i--;
202
	   linep--;
203
	   y -= get_logical_num_lines (linep);
204
	}
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
205
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
206
      if (y < 0 || i > 0)
207
	up_flag = 1;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
208
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
209
      do
210
	{
211
	  int column;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
212
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
213
	  for (column = 0;
214
	       column <= linep->len && y < GRUB_TERM_NUM_ENTRIES;
215
	       column += GRUB_TERM_ENTRY_WIDTH, y++)
216
	    {
217
	      if (y < 0)
218
		continue;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
219
	      
1.1.2 by Otavio Salvador
Import upstream version 1.92
220
	      if (i == region_start)
221
		{
222
		  if (region_column >= column
223
		      && region_column < column + GRUB_TERM_ENTRY_WIDTH)
224
		    print_line (linep, column, region_column - column, y);
225
		  else if (region_column < column)
226
		    print_line (linep, column, 0, y);
227
		}
228
	      else if (i > region_start && mode == ALL_LINES)
229
		print_line (linep, column, 0, y);
230
	    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
231
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
232
	  if (y == GRUB_TERM_NUM_ENTRIES)
233
	    {
234
	      if (column <= linep->len || i + 1 < screen->num_lines)
235
		down_flag = 1;
236
	    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
237
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
238
	  linep++;
239
	  i++;
240
241
	  if (mode == ALL_LINES && i == screen->num_lines)
242
	    for (; y < GRUB_TERM_NUM_ENTRIES; y++)
243
	      print_empty_line (y);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
244
		  
1.1.2 by Otavio Salvador
Import upstream version 1.92
245
	}
246
      while (y < GRUB_TERM_NUM_ENTRIES);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
247
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
248
      /* Draw up and down arrows.  */
249
      if (up)
250
	print_up (up_flag);
251
      if (down)
252
	print_down (down_flag);
253
    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
254
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
255
  /* Place the cursor.  */
256
  grub_gotoxy (GRUB_TERM_LEFT_BORDER_X + GRUB_TERM_MARGIN + 1 + screen->x,
257
	       GRUB_TERM_FIRST_ENTRY_Y + screen->y);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
258
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
259
  grub_refresh ();
260
}
261
262
/* Insert the string S into the screen SCREEN. This updates the cursor
263
   position and redraw the screen. Return zero if fails.  */
264
static int
265
insert_string (struct screen *screen, char *s, int update)
266
{
267
  int region_start = screen->num_lines;
268
  int region_column = 0;
269
  int down = 0;
270
  enum update_mode mode = NO_LINE;
271
272
  while (*s)
273
    {
274
      if (*s == '\n')
275
	{
276
	  /* LF is special because it creates a new line.  */
277
	  struct line *current_linep;
278
	  struct line *next_linep;
279
	  int size;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
280
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
281
	  /* Make a new line.  */
282
	  screen->num_lines++;
283
	  screen->lines = grub_realloc (screen->lines,
284
					screen->num_lines
285
					* sizeof (struct line));
286
	  if (! screen->lines)
287
	    return 0;
288
289
	  /* Scroll down. */
290
	  grub_memmove (screen->lines + screen->line + 2,
291
			screen->lines + screen->line + 1,
292
			((screen->num_lines - screen->line - 2)
293
			 * sizeof (struct line)));
294
295
	  if (! init_line (screen->lines + screen->line + 1))
296
	    return 0;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
297
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
298
	  /* Fold the line.  */
299
	  current_linep = screen->lines + screen->line;
300
	  next_linep = current_linep + 1;
301
	  size = current_linep->len - screen->column;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
302
	      
1.1.2 by Otavio Salvador
Import upstream version 1.92
303
	  if (! ensure_space (next_linep, size))
304
	    return 0;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
305
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
306
	  grub_memmove (next_linep->buf,
307
			current_linep->buf + screen->column,
308
			size);
309
	  current_linep->len = screen->column;
310
	  next_linep->len = size;
311
312
	  /* Update a dirty region.  */
313
	  if (region_start > screen->line)
314
	    {
315
	      region_start = screen->line;
316
	      region_column = screen->column;
317
	    }
318
319
	  mode = ALL_LINES;
320
	  down = 1; /* XXX not optimal.  */
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
321
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
322
	  /* Move the cursor.  */
323
	  screen->column = screen->real_column = 0;
324
	  screen->line++;
325
	  screen->x = 0;
326
	  screen->y++;
327
328
	  s++;
329
	}
330
      else
331
	{
332
	  /* All but LF.  */
333
	  char *p;
334
	  struct line *current_linep;
335
	  int size;
336
	  int orig_num, new_num;
337
1.1.8 by Robert Millan
Import upstream version 1.95+20080128
338
	  /* Find a string delimited by LF.  */
1.1.2 by Otavio Salvador
Import upstream version 1.92
339
	  p = grub_strchr (s, '\n');
340
	  if (! p)
341
	    p = s + grub_strlen (s);
342
343
	  /* Insert the string.  */
344
	  current_linep = screen->lines + screen->line;
345
	  size = p - s;
346
	  if (! ensure_space (current_linep, size))
347
	    return 0;
348
349
	  grub_memmove (current_linep->buf + screen->column + size,
350
			current_linep->buf + screen->column,
351
			current_linep->len - screen->column);
352
	  grub_memmove (current_linep->buf + screen->column,
353
			s,
354
			size);
355
	  orig_num = get_logical_num_lines (current_linep);
356
	  current_linep->len += size;
357
	  new_num = get_logical_num_lines (current_linep);
358
359
	  /* Update the dirty region.  */
360
	  if (region_start > screen->line)
361
	    {
362
	      region_start = screen->line;
363
	      region_column = screen->column;
364
	    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
365
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
366
	  if (orig_num != new_num)
367
	    {
368
	      mode = ALL_LINES;
369
	      down = 1; /* XXX not optimal.  */
370
	    }
371
	  else if (mode != ALL_LINES)
372
	    mode = SINGLE_LINE;
373
374
	  /* Move the cursor.  */
375
	  screen->column += size;
376
	  screen->real_column = screen->column;
377
	  screen->x += size;
378
	  screen->y += screen->x / GRUB_TERM_ENTRY_WIDTH;
379
	  screen->x %= GRUB_TERM_ENTRY_WIDTH;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
380
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
381
	  s = p;
382
	}
383
    }
384
385
  if (update)
386
    update_screen (screen, region_start, region_column, 0, down, mode);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
387
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
388
  return 1;
389
}
390
391
/* Release the resource allocated for SCREEN.  */
392
static void
393
destroy_screen (struct screen *screen)
394
{
395
  int i;
396
397
  if (screen->lines)
398
    for (i = 0; i < screen->num_lines; i++)
399
      {
400
	struct line *linep = screen->lines + i;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
401
	
1.1.2 by Otavio Salvador
Import upstream version 1.92
402
	if (linep)
403
	  grub_free (linep->buf);
404
      }
405
406
  grub_free (screen->killed_text);
407
  grub_free (screen->lines);
408
  grub_free (screen);
409
}
410
411
/* Make a new screen.  */
412
static struct screen *
413
make_screen (grub_menu_entry_t entry)
414
{
415
  struct screen *screen;
416
417
  /* Initialize the screen.  */
418
  screen = grub_malloc (sizeof (*screen));
419
  if (! screen)
420
    return 0;
421
422
  screen->num_lines = 1;
423
  screen->column = 0;
424
  screen->real_column = 0;
425
  screen->line = 0;
426
  screen->x = 0;
427
  screen->y = 0;
428
  screen->killed_text = 0;
429
  screen->completion_shown = 0;
430
  screen->lines = grub_malloc (sizeof (struct line));
431
  if (! screen->lines)
432
    goto fail;
433
434
  /* Initialize the first line which must be always present.  */
435
  if (! init_line (screen->lines))
436
    goto fail;
1.1.3 by Otavio Salvador
Import upstream version 1.94
437
438
  insert_string (screen, (char *) entry->sourcecode, 0);
1.1.2 by Otavio Salvador
Import upstream version 1.92
439
440
  /* Reset the cursor position.  */
441
  screen->column = 0;
442
  screen->real_column = 0;
443
  screen->line = 0;
444
  screen->x = 0;
445
  screen->y = 0;
446
447
  return screen;
448
449
 fail:
450
  destroy_screen (screen);
451
  return 0;
452
}
453
454
static int
455
forward_char (struct screen *screen, int update)
456
{
457
  struct line *linep;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
458
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
459
  linep = screen->lines + screen->line;
460
  if (screen->column < linep->len)
461
    {
462
      screen->column++;
463
      screen->x++;
464
      if (screen->x == GRUB_TERM_ENTRY_WIDTH)
465
	{
466
	  screen->x = 0;
467
	  screen->y++;
468
	}
469
    }
470
  else if (screen->num_lines > screen->line + 1)
471
    {
472
      screen->column = 0;
473
      screen->line++;
474
      screen->x = 0;
475
      screen->y++;
476
    }
477
478
  screen->real_column = screen->column;
479
480
  if (update)
481
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
482
  return 1;
483
}
484
485
static int
486
backward_char (struct screen *screen, int update)
487
{
488
  if (screen->column > 0)
489
    {
490
      screen->column--;
491
      screen->x--;
492
      if (screen->x == -1)
493
	{
494
	  screen->x = GRUB_TERM_ENTRY_WIDTH - 1;
495
	  screen->y--;
496
	}
497
    }
498
  else if (screen->line > 0)
499
    {
500
      struct line *linep;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
501
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
502
      screen->line--;
503
      linep = screen->lines + screen->line;
504
      screen->column = linep->len;
505
      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
506
      screen->y--;
507
    }
508
509
  screen->real_column = screen->column;
510
511
  if (update)
512
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
513
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
514
  return 1;
515
}
516
517
static int
518
previous_line (struct screen *screen, int update)
519
{
520
  if (screen->line > 0)
521
    {
522
      struct line *linep;
523
      int dy;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
524
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
525
      /* How many physical lines from the current position
526
	 to the first physical line?  */
527
      dy = screen->column / GRUB_TERM_ENTRY_WIDTH;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
528
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
529
      screen->line--;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
530
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
531
      linep = screen->lines + screen->line;
532
      if (linep->len < screen->real_column)
533
	screen->column = linep->len;
534
      else
535
	screen->column = screen->real_column;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
536
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
537
      /* How many physical lines from the current position
538
	 to the last physical line?  */
539
      dy += (linep->len / GRUB_TERM_ENTRY_WIDTH
540
	     - screen->column / GRUB_TERM_ENTRY_WIDTH);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
541
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
542
      screen->y -= dy + 1;
543
      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
544
    }
545
  else
546
    {
547
      screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
548
      screen->column = 0;
549
      screen->x = 0;
550
    }
551
552
  if (update)
553
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
554
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
555
  return 1;
556
}
557
558
static int
559
next_line (struct screen *screen, int update)
560
{
561
  if (screen->line < screen->num_lines - 1)
562
    {
563
      struct line *linep;
564
      int dy;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
565
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
566
      /* How many physical lines from the current position
567
	 to the last physical line?  */
568
      linep = screen->lines + screen->line;
569
      dy = (linep->len / GRUB_TERM_ENTRY_WIDTH
570
	    - screen->column / GRUB_TERM_ENTRY_WIDTH);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
571
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
572
      screen->line++;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
573
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
574
      linep++;
575
      if (linep->len < screen->real_column)
576
	screen->column = linep->len;
577
      else
578
	screen->column = screen->real_column;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
579
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
580
      /* How many physical lines from the current position
581
	 to the first physical line?  */
582
      dy += screen->column / GRUB_TERM_ENTRY_WIDTH;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
583
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
584
      screen->y += dy + 1;
585
      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
586
    }
587
  else
588
    {
589
      struct line *linep;
590
591
      linep = screen->lines + screen->line;
592
      screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
593
		    - screen->column / GRUB_TERM_ENTRY_WIDTH);
594
      screen->column = linep->len;
595
      screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
596
    }
597
598
  if (update)
599
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
600
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
601
  return 1;
602
}
603
604
static int
605
beginning_of_line (struct screen *screen, int update)
606
{
607
  screen->y -= screen->column / GRUB_TERM_ENTRY_WIDTH;
608
  screen->column = screen->real_column = 0;
609
  screen->x = 0;
610
611
  if (update)
612
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
613
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
614
  return 1;
615
}
616
617
static int
618
end_of_line (struct screen *screen, int update)
619
{
620
  struct line *linep;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
621
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
622
  linep = screen->lines + screen->line;
623
  screen->y += (linep->len / GRUB_TERM_ENTRY_WIDTH
624
		- screen->column / GRUB_TERM_ENTRY_WIDTH);
625
  screen->column = screen->real_column = linep->len;
626
  screen->x = screen->column % GRUB_TERM_ENTRY_WIDTH;
627
628
  if (update)
629
    update_screen (screen, screen->num_lines, 0, 0, 0, NO_LINE);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
630
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
631
  return 1;
632
}
633
634
static int
635
delete_char (struct screen *screen, int update)
636
{
637
  struct line *linep;
638
  enum update_mode mode = NO_LINE;
639
  int start = screen->num_lines;
640
  int column = 0;
641
  int down = 0;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
642
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
643
  linep = screen->lines + screen->line;
644
  if (linep->len > screen->column)
645
    {
646
      int orig_num, new_num;
647
648
      orig_num = get_logical_num_lines (linep);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
649
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
650
      grub_memmove (linep->buf + screen->column,
651
		    linep->buf + screen->column + 1,
652
		    linep->len - screen->column - 1);
653
      linep->len--;
654
655
      new_num = get_logical_num_lines (linep);
656
657
      if (orig_num != new_num)
658
	mode = ALL_LINES;
659
      else
660
	mode = SINGLE_LINE;
661
662
      start = screen->line;
663
      column = screen->column;
664
    }
665
  else if (screen->num_lines > screen->line + 1)
666
    {
667
      struct line *next_linep;
668
669
      next_linep = linep + 1;
670
      if (! ensure_space (linep, next_linep->len))
671
	return 0;
672
673
      grub_memmove (linep->buf + linep->len, next_linep->buf, next_linep->len);
674
      linep->len += next_linep->len;
675
676
      grub_free (next_linep->buf);
677
      grub_memmove (next_linep,
678
		    next_linep + 1,
679
		    (screen->num_lines - screen->line - 2)
680
		    * sizeof (struct line));
681
      screen->num_lines--;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
682
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
683
      mode = ALL_LINES;
684
      start = screen->line;
685
      column = screen->column;
686
      down = 1;
687
    }
688
689
  screen->real_column = screen->column;
690
691
  if (update)
692
    update_screen (screen, start, column, 0, down, mode);
693
694
  return 1;
695
}
696
697
static int
698
backward_delete_char (struct screen *screen, int update)
699
{
700
  int saved_column;
701
  int saved_line;
702
703
  saved_column = screen->column;
704
  saved_line = screen->line;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
705
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
706
  if (! backward_char (screen, 0))
707
    return 0;
708
709
  if (saved_column != screen->column || saved_line != screen->line)
710
    if (! delete_char (screen, update))
711
      return 0;
712
713
  return 1;
714
}
715
716
static int
717
kill_line (struct screen *screen, int continuous, int update)
718
{
719
  struct line *linep;
720
  char *p;
721
  int size;
722
  int offset;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
723
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
724
  p = screen->killed_text;
725
  if (! continuous && p)
726
    p[0] = '\0';
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
727
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
728
  linep = screen->lines + screen->line;
729
  size = linep->len - screen->column;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
730
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
731
  if (p)
732
    offset = grub_strlen (p);
733
  else
734
    offset = 0;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
735
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
736
  if (size > 0)
737
    {
738
      enum update_mode mode = SINGLE_LINE;
739
      int down = 0;
740
      int orig_num, new_num;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
741
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
742
      p = grub_realloc (p, offset + size + 1);
743
      if (! p)
744
	return 0;
745
746
      grub_memmove (p + offset, linep->buf + screen->column, size);
747
      p[offset + size - 1] = '\0';
748
749
      screen->killed_text = p;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
750
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
751
      orig_num = get_logical_num_lines (linep);
752
      linep->len = screen->column;
753
      new_num = get_logical_num_lines (linep);
754
755
      if (orig_num != new_num)
756
	{
757
	  mode = ALL_LINES;
758
	  down = 1;
759
	}
760
761
      if (update)
762
	update_screen (screen, screen->line, screen->column, 0, down, mode);
763
    }
764
  else if (screen->line + 1 < screen->num_lines)
765
    {
766
      p = grub_realloc (p, offset + 1 + 1);
767
      if (! p)
768
	return 0;
769
770
      p[offset] = '\n';
771
      p[offset + 1] = '\0';
772
773
      screen->killed_text = p;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
774
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
775
      return delete_char (screen, update);
776
    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
777
    
1.1.2 by Otavio Salvador
Import upstream version 1.92
778
  return 1;
779
}
780
781
static int
782
yank (struct screen *screen, int update)
783
{
784
  if (screen->killed_text)
785
    return insert_string (screen, screen->killed_text, update);
786
787
  return 1;
788
}
789
790
static int
791
open_line (struct screen *screen, int update)
792
{
793
  int saved_y = screen->y;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
794
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
795
  if (! insert_string (screen, "\n", 0))
796
    return 0;
797
798
  if (! backward_char (screen, 0))
799
    return 0;
800
801
  screen->y = saved_y;
802
803
  if (update)
804
    update_screen (screen, screen->line, screen->column, 0, 1, ALL_LINES);
805
806
  return 1;
807
}
808
809
/* A completion hook to print items.  */
810
static void
811
store_completion (const char *item, grub_completion_type_t type, int count)
812
{
813
  char *p;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
814
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
815
  if (count == 0)
816
    {
817
      /* If this is the first time, print a label.  */
818
      const char *what;
819
820
      switch (type)
821
	{
822
	case GRUB_COMPLETION_TYPE_COMMAND:
823
	  what = "commands";
824
	  break;
825
	case GRUB_COMPLETION_TYPE_DEVICE:
826
	  what = "devices";
827
	  break;
828
	case GRUB_COMPLETION_TYPE_FILE:
829
	  what = "files";
830
	  break;
831
	case GRUB_COMPLETION_TYPE_PARTITION:
832
	  what = "partitions";
833
	  break;
834
	case GRUB_COMPLETION_TYPE_ARGUMENT:
835
	  what = "arguments";
836
	  break;
837
	default:
838
	  what = "things";
839
	  break;
840
	}
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
841
	    
1.1.2 by Otavio Salvador
Import upstream version 1.92
842
      grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
843
      grub_printf ("   Possible %s are:\n    ", what);
844
    }
845
846
  /* Make sure that the completion buffer has enough room.  */
847
  if (completion_buffer.max_len < (completion_buffer.len
848
				   + (int) grub_strlen (item) + 1 + 1))
849
    {
850
      grub_size_t new_len;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
851
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
852
      new_len = completion_buffer.len + grub_strlen (item) + 80;
853
      p = grub_realloc (completion_buffer.buf, new_len);
854
      if (! p)
855
	{
856
	  /* Possibly not fatal.  */
857
	  grub_errno = GRUB_ERR_NONE;
858
	  return;
859
	}
860
      p[completion_buffer.len] = 0;
861
      completion_buffer.buf = p;
862
      completion_buffer.max_len = new_len;
863
    }
864
865
  p = completion_buffer.buf + completion_buffer.len;
866
  if (completion_buffer.len != 0)
867
    {
868
      *p++ = ' ';
869
      completion_buffer.len++;
870
    }
871
  grub_strcpy (p, item);
872
  completion_buffer.len += grub_strlen (item);
873
}
874
875
static int
876
complete (struct screen *screen, int continuous, int update)
877
{
878
  grub_uint16_t pos;
879
  char saved_char;
880
  struct line *linep;
881
  int restore;
882
  char *insert;
883
  static int count = -1;
884
885
  if (continuous)
886
    count++;
887
  else
888
    count = 0;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
889
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
890
  pos = grub_getxy ();
891
  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
892
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
893
  completion_buffer.buf = 0;
894
  completion_buffer.len = 0;
895
  completion_buffer.max_len = 0;
896
897
  linep = screen->lines + screen->line;
898
  saved_char = linep->buf[screen->column];
899
  linep->buf[screen->column] = '\0';
900
901
  insert = grub_normal_do_completion (linep->buf, &restore, store_completion);
902
903
  linep->buf[screen->column] = saved_char;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
904
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
905
  if (restore)
906
    {
907
      char *p = completion_buffer.buf;
908
909
      screen->completion_shown = 1;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
910
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
911
      if (p)
912
	{
913
	  int num_sections = ((completion_buffer.len + GRUB_TERM_WIDTH - 8 - 1)
914
			      / (GRUB_TERM_WIDTH - 8));
915
	  char *endp;
916
917
	  p += (count % num_sections) * (GRUB_TERM_WIDTH - 8);
918
	  endp = p + (GRUB_TERM_WIDTH - 8);
919
920
	  if (p != completion_buffer.buf)
921
	    grub_putcode (GRUB_TERM_DISP_LEFT);
922
	  else
923
	    grub_putchar (' ');
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
924
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
925
	  while (*p && p < endp)
926
	    grub_putchar (*p++);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
927
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
928
	  if (*p)
929
	    grub_putcode (GRUB_TERM_DISP_RIGHT);
930
	}
931
    }
932
933
  grub_gotoxy (pos >> 8, pos & 0xFF);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
934
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
935
  if (insert)
936
    {
937
      insert_string (screen, insert, update);
938
      count = -1;
939
      grub_free (insert);
940
    }
941
  else if (update)
942
    grub_refresh ();
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
943
    
1.1.2 by Otavio Salvador
Import upstream version 1.92
944
  grub_free (completion_buffer.buf);
945
  return 1;
946
}
947
948
/* Clear displayed completions.  */
949
static void
950
clear_completions (void)
951
{
952
  grub_uint16_t pos;
953
  int i, j;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
954
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
955
  pos = grub_getxy ();
956
  grub_gotoxy (0, GRUB_TERM_HEIGHT - 3);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
957
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
958
  for (i = 0; i < 2; i++)
959
    {
960
      for (j = 0; j < GRUB_TERM_WIDTH - 1; j++)
961
	grub_putchar (' ');
962
      grub_putchar ('\n');
963
    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
964
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
965
  grub_gotoxy (pos >> 8, pos & 0xFF);
966
  grub_refresh ();
967
}
968
969
/* Execute the command list in the screen SCREEN.  */
970
static int
971
run (struct screen *screen)
972
{
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
973
  struct grub_script *parsed_script = 0;
1.1.3 by Otavio Salvador
Import upstream version 1.94
974
  int currline = 0;
975
  char *nextline;
976
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
977
  auto grub_err_t editor_getline (char **line);
978
  grub_err_t editor_getline (char **line)
1.1.2 by Otavio Salvador
Import upstream version 1.92
979
    {
1.1.3 by Otavio Salvador
Import upstream version 1.94
980
      struct line *linep = screen->lines + currline;
1.1.2 by Otavio Salvador
Import upstream version 1.92
981
      char *p;
1.1.3 by Otavio Salvador
Import upstream version 1.94
982
983
      if (currline > screen->num_lines)
984
	{
985
	  *line = 0;
986
	  return 0;
987
	}
988
1.1.2 by Otavio Salvador
Import upstream version 1.92
989
      /* Trim down space characters.  */
990
      for (p = linep->buf + linep->len - 1;
991
	   p >= linep->buf && grub_isspace (*p);
992
	   p--)
993
	;
994
      *++p = '\0';
1.1.3 by Otavio Salvador
Import upstream version 1.94
995
1.1.2 by Otavio Salvador
Import upstream version 1.92
996
      linep->len = p - linep->buf;
997
      for (p = linep->buf; grub_isspace (*p); p++)
998
	;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
999
      *line = p;
1.1.3 by Otavio Salvador
Import upstream version 1.94
1000
      currline++;
1001
      return 0;
1002
    }
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1003
  
1.1.3 by Otavio Salvador
Import upstream version 1.94
1004
  grub_cls ();
1005
  grub_printf ("  Booting a command list\n\n");
1006
1007
1008
  /* Execute the script, line for line.  */
1.1.5 by Albin Tonnerre
Import upstream version 1.95+20070520
1009
  while (currline < screen->num_lines)
1.1.3 by Otavio Salvador
Import upstream version 1.94
1010
    {
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1011
      editor_getline (&nextline);
1012
      parsed_script = grub_script_parse (nextline, editor_getline);
1013
      if (parsed_script)
1014
	{
1015
	  /* Execute the command(s).  */
1016
	  grub_script_execute (parsed_script);
1017
	  
1018
	  /* The parsed script was executed, throw it away.  */
1019
	  grub_script_free (parsed_script);
1020
	}
1021
      else
1.1.2 by Otavio Salvador
Import upstream version 1.92
1022
	break;
1023
    }
1024
1.1.5 by Albin Tonnerre
Import upstream version 1.95+20070520
1025
  if (grub_errno == GRUB_ERR_NONE && grub_loader_is_loaded ())
1026
    /* Implicit execution of boot, only if something is loaded.  */
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1027
    grub_command_execute ("boot", 0);
1.1.5 by Albin Tonnerre
Import upstream version 1.95+20070520
1028
1.1.2 by Otavio Salvador
Import upstream version 1.92
1029
  if (grub_errno != GRUB_ERR_NONE)
1030
    {
1031
      grub_print_error ();
1032
      grub_errno = GRUB_ERR_NONE;
1.1.8 by Robert Millan
Import upstream version 1.95+20080128
1033
      grub_wait_after_message ();
1.1.2 by Otavio Salvador
Import upstream version 1.92
1034
    }
1.1.3 by Otavio Salvador
Import upstream version 1.94
1035
1.1.2 by Otavio Salvador
Import upstream version 1.92
1036
  return 1;
1037
}
1038
1039
/* Edit a menu entry with an Emacs-like interface.  */
1040
void
1041
grub_menu_entry_run (grub_menu_entry_t entry)
1042
{
1043
  struct screen *screen;
1044
  int prev_c;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1045
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1046
  screen = make_screen (entry);
1047
  if (! screen)
1048
    return;
1049
1050
 refresh:
1051
  /* Draw the screen.  */
1052
  grub_menu_init_page (0, 1);
1053
  update_screen (screen, 0, 0, 1, 1, ALL_LINES);
1054
  grub_setcursor (1);
1055
  prev_c = '\0';
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1056
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1057
  while (1)
1058
    {
1059
      int c = GRUB_TERM_ASCII_CHAR (grub_getkey ());
1060
1061
      if (screen->completion_shown)
1062
	{
1063
	  clear_completions ();
1064
	  screen->completion_shown = 0;
1065
	}
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1066
      
1.1.2 by Otavio Salvador
Import upstream version 1.92
1067
      switch (c)
1068
	{
1069
	case 16: /* C-p */
1070
	  if (! previous_line (screen, 1))
1071
	    goto fail;
1072
	  break;
1073
1074
	case 14: /* C-n */
1075
	  if (! next_line (screen, 1))
1076
	    goto fail;
1077
	  break;
1078
1079
	case 6: /* C-f */
1080
	  if (! forward_char (screen, 1))
1081
	    goto fail;
1082
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1083
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1084
	case 2: /* C-b */
1085
	  if (! backward_char (screen, 1))
1086
	    goto fail;
1087
	  break;
1088
1089
	case 1: /* C-a */
1090
	  if (! beginning_of_line (screen, 1))
1091
	    goto fail;
1092
	  break;
1093
1094
	case 5: /* C-e */
1095
	  if (! end_of_line (screen, 1))
1096
	    goto fail;
1097
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1098
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1099
	case '\t': /* C-i */
1100
	  if (! complete (screen, prev_c == c, 1))
1101
	    goto fail;
1102
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1103
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1104
	case 4: /* C-d */
1105
	  if (! delete_char (screen, 1))
1106
	    goto fail;
1107
	  break;
1108
1109
	case 8: /* C-h */
1110
	  if (! backward_delete_char (screen, 1))
1111
	    goto fail;
1112
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1113
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1114
	case 11: /* C-k */
1115
	  if (! kill_line (screen, prev_c == c, 1))
1116
	    goto fail;
1117
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1118
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1119
	case 21: /* C-u */
1120
	  /* FIXME: What behavior is good for this key?  */
1121
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1122
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1123
	case 25: /* C-y */
1124
	  if (! yank (screen, 1))
1125
	    goto fail;
1126
	  break;
1127
1128
	case 12: /* C-l */
1129
	  /* FIXME: centering.  */
1130
	  goto refresh;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1131
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1132
	case 15: /* C-o */
1133
	  if (! open_line (screen, 1))
1134
	    goto fail;
1135
	  break;
1136
1137
	case '\n':
1138
	case '\r':
1139
	  if (! insert_string (screen, "\n", 1))
1140
	    goto fail;
1141
	  break;
1142
1143
	case '\e':
1144
	  destroy_screen (screen);
1145
	  return;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1146
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1147
	case 3: /* C-c */
1148
	  grub_cmdline_run (1);
1149
	  goto refresh;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1150
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1151
	case 24: /* C-x */
1152
	  if (! run (screen))
1153
	    goto fail;
1154
	  goto refresh;
1155
1156
	case 18: /* C-r */
1157
	case 19: /* C-s */
1158
	case 20: /* C-t */
1159
	  /* FIXME */
1160
	  break;
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1161
	  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1162
	default:
1163
	  if (grub_isprint (c))
1164
	    {
1165
	      char buf[2];
1166
1167
	      buf[0] = c;
1168
	      buf[1] = '\0';
1169
	      if (! insert_string (screen, buf, 1))
1170
		goto fail;
1171
	    }
1172
	  break;
1173
	}
1174
1175
      prev_c = c;
1176
    }
1177
1178
 fail:
1179
  destroy_screen (screen);
1.1.11 by Robert Millan
Import upstream version 1.96+20080724
1180
  
1.1.2 by Otavio Salvador
Import upstream version 1.92
1181
  grub_cls ();
1182
  grub_print_error ();
1183
  grub_errno = GRUB_ERR_NONE;
1184
  grub_printf ("\nPress any key to continue...");
1185
  (void) grub_getkey ();
1186
}