handle special key codes in a serial terminal, and remove unnecessary push/pop operations in asm.S.
This commit is contained in:
parent
3c5fa0cfe3
commit
16cbb2b422
6 changed files with 216 additions and 106 deletions
38
ChangeLog
38
ChangeLog
|
@ -1,3 +1,41 @@
|
|||
2000-08-26 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
Don't save/restore fragile registers unnecessarily.
|
||||
|
||||
* stage2/asm.S [!STAGE1_5] (track_int13): Don't save/restore
|
||||
%ecx, %edx, or %eax.
|
||||
[!STAGE1_5] (set_int13_handler): Likewise.
|
||||
(biosdisk_int13_extensions): Likewise.
|
||||
(biosdisk_standard): Likewise.
|
||||
(check_int13_extensions): Likewise.
|
||||
(get_diskinfo_int13_extensions): Likewise.
|
||||
(get_diskinfo_standard): Likewise.
|
||||
(get_diskinfo_floppy): Likewise.
|
||||
[!STAGE1_5] (get_eisamemsize): Likewise.
|
||||
[!STAGE1_5] (get_mmap_entry): Likewise.
|
||||
[!STAGE1_5] (console_cls): Likewise.
|
||||
[!STAGE1_5] (nocursor): Likewise.
|
||||
[!STAGE1_5] (console_getxy): Likewise.
|
||||
[!STAGE1_5] (console_gotoxy): Likewise.
|
||||
[!STAGE1_5] (set_attrib): Likewise.
|
||||
[!STAGE1_5] (getrtsecs): Likewise.
|
||||
[!STAGE1_5] (currticks): Likewise, and don't zero %eax
|
||||
explicitly, since prot_to_real does that.
|
||||
|
||||
2000-08-25 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
* stage2/char_io.c [!STAGE1_5] (translate_keycode): New
|
||||
function. The serial part is stolen from the patch by Christoph
|
||||
Plattner.
|
||||
[!STAGE1_5] (get_cmdline): Call translate_keycode instead of
|
||||
translating special key codes into ASCII characters by itself.
|
||||
* stage2/stage2.c (run_menu): Wrap getkey with the macro
|
||||
ASCII_CHAR, when checking if ESC is pressed.
|
||||
Call translate_keycode as well as getkey, unless checkkey
|
||||
returns -1. So don't check if C is KEY_DOWN or KEY_UP. And don't
|
||||
use the macro ASCII_CHAR for C explicitly.
|
||||
* stage2/shared.h (translate_keycode): Declared.
|
||||
|
||||
2000-08-24 OKUJI Yoshinori <okuji@gnu.org>
|
||||
|
||||
* stage2/builtins.c [GRUB_UTIL]: Include stdio.h before
|
||||
|
|
|
@ -432,6 +432,31 @@ getrtsecs (void)
|
|||
return time (0);
|
||||
}
|
||||
|
||||
int
|
||||
currticks (void)
|
||||
{
|
||||
struct timeval tv;
|
||||
long csecs;
|
||||
int ticks_per_csec, ticks_per_usec;
|
||||
|
||||
/* Note: 18.2 ticks/sec. */
|
||||
|
||||
/* Get current time. */
|
||||
gettimeofday (&tv, 0);
|
||||
|
||||
/* Compute centiseconds. */
|
||||
csecs = tv.tv_sec / 10;
|
||||
|
||||
/* Ticks per centisecond. */
|
||||
ticks_per_csec = csecs * 182;
|
||||
|
||||
/* Ticks per microsecond. */
|
||||
ticks_per_usec = (((tv.tv_sec - csecs * 10) * 1000000 + tv.tv_usec)
|
||||
* 182 / 10000000);
|
||||
|
||||
/* Sum them. */
|
||||
return ticks_per_csec + ticks_per_usec;
|
||||
}
|
||||
|
||||
/* low-level character I/O */
|
||||
void
|
||||
|
|
95
stage2/asm.S
95
stage2/asm.S
|
@ -18,6 +18,23 @@
|
|||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
* Note: These functions defined in this file may be called from C.
|
||||
* Be careful of that you must not modify some registers. Quote
|
||||
* from gcc-2.95.2/gcc/config/i386/i386.h:
|
||||
|
||||
1 for registers not available across function calls.
|
||||
These must include the FIXED_REGISTERS and also any
|
||||
registers that can be used without being saved.
|
||||
The latter must include the registers where values are returned
|
||||
and the register where structure-value addresses are passed.
|
||||
Aside from that, you can include as many other registers as you like.
|
||||
|
||||
ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg
|
||||
{ 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }
|
||||
*/
|
||||
|
||||
#define ASM_FILE
|
||||
|
||||
#include "shared.h"
|
||||
|
@ -258,7 +275,6 @@ ENTRY(track_int13)
|
|||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
pushl %edx
|
||||
pushl %ebx
|
||||
pushl %edi
|
||||
|
||||
|
@ -310,7 +326,6 @@ ENTRY(track_int13)
|
|||
|
||||
popl %edi
|
||||
popl %ebx
|
||||
popl %edx
|
||||
popl %ebp
|
||||
|
||||
ret
|
||||
|
@ -605,7 +620,6 @@ ENTRY(set_int13_handler)
|
|||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
pushl %ecx
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
|
||||
|
@ -649,7 +663,6 @@ ENTRY(set_int13_handler)
|
|||
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %ecx
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
|
@ -938,8 +951,6 @@ ENTRY(biosdisk_int13_extensions)
|
|||
pushl %ebp
|
||||
movl %esp, %ebp
|
||||
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
|
||||
/* compute the address of disk_address_packet */
|
||||
|
@ -971,8 +982,6 @@ ENTRY(biosdisk_int13_extensions)
|
|||
movb %dl, %al /* return value in %eax */
|
||||
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebp
|
||||
|
||||
ret
|
||||
|
@ -991,8 +1000,6 @@ ENTRY(biosdisk_standard)
|
|||
movl %esp, %ebp
|
||||
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %edi
|
||||
pushl %esi
|
||||
|
||||
|
@ -1044,8 +1051,6 @@ ENTRY(biosdisk_standard)
|
|||
|
||||
popl %esi
|
||||
popl %edi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
|
||||
|
@ -1064,8 +1069,6 @@ ENTRY(check_int13_extensions)
|
|||
movl %esp, %ebp
|
||||
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
/* drive */
|
||||
movb 0x8(%ebp), %dl
|
||||
|
@ -1100,8 +1103,6 @@ ENTRY(check_int13_extensions)
|
|||
|
||||
movb %bl, %al /* return value in %eax */
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
|
||||
|
@ -1120,7 +1121,6 @@ ENTRY(get_diskinfo_int13_extensions)
|
|||
movl %esp, %ebp
|
||||
|
||||
pushl %ebx
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
|
||||
/* compute the address of drive parameters */
|
||||
|
@ -1149,7 +1149,6 @@ ENTRY(get_diskinfo_int13_extensions)
|
|||
movb %bl, %al /* return value in %eax */
|
||||
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
|
||||
|
@ -1169,8 +1168,6 @@ ENTRY(get_diskinfo_standard)
|
|||
movl %esp, %ebp
|
||||
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %edi
|
||||
|
||||
/* drive */
|
||||
|
@ -1196,7 +1193,7 @@ ENTRY(get_diskinfo_standard)
|
|||
.code32
|
||||
|
||||
/* restore %ebp */
|
||||
leal 0x10(%esp), %ebp
|
||||
leal 0x8(%esp), %ebp
|
||||
|
||||
/* heads */
|
||||
movb %dh, %al
|
||||
|
@ -1224,8 +1221,6 @@ ENTRY(get_diskinfo_standard)
|
|||
movb %bl, %al /* return value in %eax */
|
||||
|
||||
popl %edi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
|
||||
|
@ -1245,8 +1240,6 @@ ENTRY(get_diskinfo_floppy)
|
|||
movl %esp, %ebp
|
||||
|
||||
pushl %ebx
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
pushl %esi
|
||||
|
||||
/* drive */
|
||||
|
@ -1291,7 +1284,7 @@ probe_values:
|
|||
.code32
|
||||
|
||||
/* restore %ebp */
|
||||
leal 0x10(%esp), %ebp
|
||||
leal 0x8(%esp), %ebp
|
||||
|
||||
/* cylinders */
|
||||
movl 0xc(%ebp), %eax
|
||||
|
@ -1313,8 +1306,6 @@ probe_values:
|
|||
incl %eax /* %eax = 1 (non-zero) */
|
||||
3:
|
||||
popl %esi
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebx
|
||||
popl %ebp
|
||||
|
||||
|
@ -1505,8 +1496,6 @@ xdone:
|
|||
ENTRY(get_eisamemsize)
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call EXT_C(prot_to_real) /* enter real mode */
|
||||
.code16
|
||||
|
@ -1527,8 +1516,6 @@ ENTRY(get_eisamemsize)
|
|||
movl %ebx, %eax
|
||||
|
||||
xnoteisa:
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
@ -1549,13 +1536,11 @@ xnoteisa:
|
|||
ENTRY(get_mmap_entry)
|
||||
push %ebp
|
||||
push %ebx
|
||||
push %ecx
|
||||
push %edx
|
||||
push %edi
|
||||
push %esi
|
||||
|
||||
/* place address (+4) in ES:DI */
|
||||
movl 0x1c(%esp), %eax
|
||||
movl 0x14(%esp), %eax
|
||||
addl $4, %eax
|
||||
movl %eax, %edi
|
||||
andl $0xf, %edi
|
||||
|
@ -1563,7 +1548,7 @@ ENTRY(get_mmap_entry)
|
|||
movl %eax, %esi
|
||||
|
||||
/* set continuation value */
|
||||
movl 0x20(%esp), %ebx
|
||||
movl 0x18(%esp), %ebx
|
||||
|
||||
/* set default maximum buffer size */
|
||||
movl $0x14, %ecx
|
||||
|
@ -1599,7 +1584,7 @@ xsmap:
|
|||
.code32
|
||||
|
||||
/* write length of buffer (zero if error) into "addr" */
|
||||
movl 0x1c(%esp), %eax
|
||||
movl 0x14(%esp), %eax
|
||||
movl %ecx, (%eax)
|
||||
|
||||
/* set return value to continuation */
|
||||
|
@ -1607,8 +1592,6 @@ xsmap:
|
|||
|
||||
pop %esi
|
||||
pop %edi
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
@ -1769,7 +1752,6 @@ ENTRY(multi_boot)
|
|||
|
||||
ENTRY(console_cls)
|
||||
push %ebp
|
||||
push %eax
|
||||
push %ebx /* save EBX */
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
|
@ -1784,7 +1766,6 @@ ENTRY(console_cls)
|
|||
.code32
|
||||
|
||||
pop %ebx
|
||||
pop %eax
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
@ -1799,9 +1780,7 @@ ENTRY(console_cls)
|
|||
|
||||
ENTRY(nocursor)
|
||||
push %ebp
|
||||
push %eax
|
||||
push %ebx /* save EBX */
|
||||
push %edx
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
.code16
|
||||
|
@ -1813,9 +1792,7 @@ ENTRY(nocursor)
|
|||
DATA32 call EXT_C(real_to_prot)
|
||||
.code32
|
||||
|
||||
pop %edx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
@ -1835,8 +1812,6 @@ ENTRY(nocursor)
|
|||
ENTRY(console_getxy)
|
||||
push %ebp
|
||||
push %ebx /* save EBX */
|
||||
push %ecx /* save ECX */
|
||||
push %edx
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
.code16
|
||||
|
@ -1851,8 +1826,6 @@ ENTRY(console_getxy)
|
|||
movb %dl, %ah
|
||||
movb %dh, %al
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %ebp
|
||||
ret
|
||||
|
@ -1870,12 +1843,10 @@ ENTRY(console_getxy)
|
|||
|
||||
ENTRY(console_gotoxy)
|
||||
push %ebp
|
||||
push %eax
|
||||
push %ebx /* save EBX */
|
||||
push %edx
|
||||
|
||||
movb 0x14(%esp), %dl /* %dl = x */
|
||||
movb 0x18(%esp), %dh /* %dh = y */
|
||||
movb 0xc(%esp), %dl /* %dl = x */
|
||||
movb 0x10(%esp), %dh /* %dh = y */
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
.code16
|
||||
|
@ -1887,9 +1858,7 @@ ENTRY(console_gotoxy)
|
|||
DATA32 call EXT_C(real_to_prot)
|
||||
.code32
|
||||
|
||||
pop %edx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
@ -1931,11 +1900,9 @@ ENTRY(console_gotoxy)
|
|||
|
||||
ENTRY(set_attrib)
|
||||
push %ebp
|
||||
push %eax
|
||||
push %ebx
|
||||
push %ecx
|
||||
|
||||
movl 0x14(%esp), %ecx
|
||||
movl 0xc(%esp), %ecx
|
||||
xorl %ebx, %ebx
|
||||
|
||||
call EXT_C(prot_to_real)
|
||||
|
@ -1951,9 +1918,7 @@ ENTRY(set_attrib)
|
|||
DATA32 call EXT_C(real_to_prot)
|
||||
.code32
|
||||
|
||||
pop %ecx
|
||||
pop %ebx
|
||||
pop %eax
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
@ -1978,8 +1943,6 @@ ENTRY(set_attrib)
|
|||
*/
|
||||
ENTRY(getrtsecs)
|
||||
push %ebp
|
||||
push %ecx
|
||||
push %edx
|
||||
|
||||
call EXT_C(prot_to_real) /* enter real mode */
|
||||
.code16
|
||||
|
@ -1996,8 +1959,6 @@ gottime:
|
|||
|
||||
movb %dh, %al
|
||||
|
||||
pop %edx
|
||||
pop %ecx
|
||||
pop %ebp
|
||||
ret
|
||||
|
||||
|
@ -2009,13 +1970,11 @@ gottime:
|
|||
*/
|
||||
ENTRY(currticks)
|
||||
pushl %ebp
|
||||
pushl %ecx
|
||||
pushl %edx
|
||||
|
||||
call EXT_C(prot_to_real) /* enter real mode */
|
||||
.code16
|
||||
|
||||
xorl %eax, %eax
|
||||
/* %ax is already zero */
|
||||
int $0x1a
|
||||
|
||||
DATA32 call EXT_C(real_to_prot)
|
||||
|
@ -2025,8 +1984,6 @@ ENTRY(currticks)
|
|||
shll $16, %eax
|
||||
movw %dx, %ax
|
||||
|
||||
popl %edx
|
||||
popl %ecx
|
||||
popl %ebp
|
||||
ret
|
||||
|
||||
|
|
150
stage2/char_io.c
150
stage2/char_io.c
|
@ -337,35 +337,7 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
|
||||
while (ASCII_CHAR (c = getkey ()) != '\n' && ASCII_CHAR (c) != '\r')
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
c = 2;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
c = 6;
|
||||
break;
|
||||
case KEY_UP:
|
||||
c = 16;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
c = 14;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
c = 1;
|
||||
break;
|
||||
case KEY_END:
|
||||
c = 5;
|
||||
break;
|
||||
case KEY_DC:
|
||||
c = 4;
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
c = 8;
|
||||
break;
|
||||
}
|
||||
|
||||
c = ASCII_CHAR (c);
|
||||
c = translate_keycode (c);
|
||||
|
||||
/* If READLINE is non-zero, handle readline-like key bindings. */
|
||||
if (readline)
|
||||
|
@ -618,6 +590,126 @@ get_cmdline (char *prompt, char *cmdline, int maxlen,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Translate a special key to a common ascii code. */
|
||||
int
|
||||
translate_keycode (int c)
|
||||
{
|
||||
# ifdef SUPPORT_SERIAL
|
||||
if (terminal & TERMINAL_SERIAL)
|
||||
{
|
||||
/* In a serial terminal, things are complicated, because several
|
||||
key codes start from the character ESC, while we want to accept
|
||||
ESC itself. */
|
||||
if (c == '\e')
|
||||
{
|
||||
int start;
|
||||
|
||||
/* Get current time. */
|
||||
start = currticks ();
|
||||
|
||||
while (checkkey () == -1)
|
||||
{
|
||||
/* Wait for a next character, at least for 0.1 sec
|
||||
(18.2 ticks/sec). */
|
||||
int now;
|
||||
|
||||
now = currticks ();
|
||||
if (now - start >= 2)
|
||||
return c;
|
||||
}
|
||||
|
||||
c = getkey ();
|
||||
if (c == '[')
|
||||
{
|
||||
int c1, c2;
|
||||
|
||||
/* To filter illegal states. */
|
||||
c = 0;
|
||||
c1 = getkey ();
|
||||
switch (c1)
|
||||
{
|
||||
case 'A': /* KEY_UP */
|
||||
c = 16;
|
||||
break;
|
||||
case 'B': /* KEY_DOWN */
|
||||
c = 14;
|
||||
break;
|
||||
case 'C': /* KEY_RIGHT */
|
||||
c = 6;
|
||||
break;
|
||||
case 'D': /* KEY_LEFT */
|
||||
c = 2;
|
||||
break;
|
||||
case 'F': /* End */
|
||||
c = 5;
|
||||
break;
|
||||
case 'H': /* Home */
|
||||
c = 1;
|
||||
break;
|
||||
case '1':
|
||||
c2 = getkey ();
|
||||
if (c2 == '~')
|
||||
{
|
||||
/* One of control keys (pos1,....). */
|
||||
c = 1;
|
||||
}
|
||||
break;
|
||||
case '3':
|
||||
c2 = getkey ();
|
||||
if (c2 == '~')
|
||||
{
|
||||
/* One of control keys (del,....). */
|
||||
c = 4;
|
||||
}
|
||||
break;
|
||||
case '4': /* Del */
|
||||
c = 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Drain the input buffer, because so-called VT100-compatible
|
||||
terminals could send key codes which aren't handled in the
|
||||
code above. */
|
||||
while (checkkey () != -1)
|
||||
(void) getkey ();
|
||||
}
|
||||
}
|
||||
else
|
||||
# endif /* SUPPORT_SERIAL */
|
||||
{
|
||||
switch (c)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
c = 2;
|
||||
break;
|
||||
case KEY_RIGHT:
|
||||
c = 6;
|
||||
break;
|
||||
case KEY_UP:
|
||||
c = 16;
|
||||
break;
|
||||
case KEY_DOWN:
|
||||
c = 14;
|
||||
break;
|
||||
case KEY_HOME:
|
||||
c = 1;
|
||||
break;
|
||||
case KEY_END:
|
||||
c = 5;
|
||||
break;
|
||||
case KEY_DC:
|
||||
c = 4;
|
||||
break;
|
||||
case KEY_BACKSPACE:
|
||||
c = 8;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ASCII_CHAR (c);
|
||||
}
|
||||
#endif /* STAGE1_5 */
|
||||
|
||||
int
|
||||
|
|
|
@ -798,6 +798,7 @@ int nul_terminate (char *str);
|
|||
int get_based_digit (int c, int base);
|
||||
int safe_parse_maxint (char **str_ptr, int *myint_ptr);
|
||||
int memcheck (int start, int len);
|
||||
int translate_keycode (int c);
|
||||
|
||||
#ifndef NO_DECOMPRESSION
|
||||
/* Compression support. */
|
||||
|
|
|
@ -260,7 +260,7 @@ restart:
|
|||
while (1)
|
||||
{
|
||||
/* Check if ESC is pressed. */
|
||||
if (checkkey () != -1 && getkey () == 27)
|
||||
if (checkkey () != -1 && ASCII_CHAR (getkey ()) == '\e')
|
||||
{
|
||||
grub_timeout = -1;
|
||||
show_menu = 1;
|
||||
|
@ -358,7 +358,7 @@ restart:
|
|||
|
||||
if (checkkey () != -1)
|
||||
{
|
||||
c = getkey ();
|
||||
c = translate_keycode (getkey ());
|
||||
|
||||
if (grub_timeout >= 0)
|
||||
{
|
||||
|
@ -369,7 +369,7 @@ restart:
|
|||
gotoxy (74, 4 + entryno);
|
||||
}
|
||||
|
||||
if ((c == KEY_UP) || (ASCII_CHAR (c) == 16))
|
||||
if (c == 16)
|
||||
{
|
||||
if (entryno > 0)
|
||||
{
|
||||
|
@ -386,8 +386,7 @@ restart:
|
|||
set_line_highlight (4, first_entry + entryno, menu_entries);
|
||||
}
|
||||
}
|
||||
if (((c == KEY_DOWN) || (ASCII_CHAR (c) == 14))
|
||||
&& (first_entry + entryno + 1) < num_entries)
|
||||
if (c == 14 && (first_entry + entryno + 1) < num_entries)
|
||||
{
|
||||
if (entryno < 11)
|
||||
{
|
||||
|
@ -405,8 +404,6 @@ restart:
|
|||
}
|
||||
}
|
||||
|
||||
c = ASCII_CHAR (c);
|
||||
|
||||
if (config_entries)
|
||||
{
|
||||
if ((c == '\n') || (c == '\r'))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue