Date: Sun, 6 Jun 1999 11:01:54 +0300 (IDT) From: Eli Zaretskii X-Sender: eliz AT is To: Robert Hoehne cc: djgpp-workers AT delorie DOT com Subject: GDB 4.18 alpha: more readline-related patches Message-ID: MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Note-from-DJ: This may be spam Reply-To: djgpp-workers AT delorie DOT com After some additional debugging of readline-related issues, here are a few more patches. Short descriptions of the changes: - I took out several DJGPP-specific fragments, including some that I myself introduced in the previous series of changes in readline. It turned out that the code I corrected isn't called in the DJGPP port (because the initialization code declares the related display features missing). So it seems that removing the code is cleaner than having a lot of DJGPP-specific ifdef'ed stuff. Sorry I didn't see that when I sent the previous changes. - Due to full support of signals, the code and ifdef's that removed signal-related code are no longer needed, so I removed them. - Termios support is good enough to eliminate the need to ifdef away portions of the code. - File-name completion didn't cope with d:/foo/bar style of file names, so I fixed that. - The readline init file no longer needs to be in Unix text format (curiously enough, this was about the first bug report I submitted to the DJGPP bug-tracking system years ago). - Readline now tries ~/_inputrc if the default ~/.inputrc fails (the latter could work under LFN). - History now tries ~/_history if ~/.history fails. (Although this is never used by GDB, as far as I could see.) - History no longer writes garbage at end of history file when truncating it (also never used by GDB, or so it seems). - GDB now defaults to ~/_gdb_history as its history file name. *** readline/input.c~0 Mon Dec 21 20:06:26 1998 --- readline/input.c Wed May 19 22:26:44 1999 *************** extern Keymap _rl_keymap; *** 96,105 **** extern int _rl_convert_meta_chars_to_ascii; - #if defined (__GO32__) - # include - #endif /* __GO32__ */ - /* Non-null means it is a pointer to a function to run while waiting for character input. */ Function *rl_event_hook = (Function *)NULL; --- 96,101 ---- *************** rl_unget_char (key) *** 201,217 **** static void rl_gather_tyi () { - #if defined (__GO32__) - char input; - - if (isatty (0) && kbhit () && ibuffer_space ()) - { - int i; - i = (*rl_getc_function) (rl_instream); - rl_stuff_char (i); - } - #else /* !__GO32__ */ - int tty; register int tem, result; int chars_avail; --- 197,202 ---- *************** rl_gather_tyi () *** 280,286 **** if (chars_avail) rl_stuff_char (input); } - #endif /* !__GO32__ */ } /* Is there input available to be read on the readline input file --- 265,270 ---- *************** rl_getc (stream) *** 392,402 **** int result, flags; unsigned char c; - #if defined (__GO32__) - if (isatty (0)) - return (getkey () & 0x7F); - #endif /* __GO32__ */ - while (1) { result = read (fileno (stream), &c, sizeof (unsigned char)); --- 376,381 ---- *************** rl_getc (stream) *** 438,449 **** } #endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */ - #if !defined (__GO32__) /* If the error that we received was SIGINT, then try again, this is simply an interrupted system call to read (). Otherwise, some error ocurred, also signifying EOF. */ if (errno != EINTR) return (EOF); - #endif /* !__GO32__ */ } } --- 417,426 ---- *** readline/readline.c~1 Mon May 17 18:57:18 1999 --- readline/readline.c Thu May 20 18:09:24 1999 *************** static void readline_default_bindings () *** 174,180 **** #if defined (__GO32__) # include # include - # undef HANDLE_SIGNALS #endif /* __GO32__ */ extern char *xmalloc (), *xrealloc (); --- 174,179 ---- *** readline/rltty.c~0 Tue Dec 22 21:53:32 1998 --- readline/rltty.c Thu May 20 19:20:02 1999 *************** extern int _rl_enable_keypad, _rl_enable *** 55,65 **** extern void _rl_control_keypad (); - #if defined (__GO32__) - # include - # undef HANDLE_SIGNALS - #endif /* __GO32__ */ - /* Indirect functions to allow apps control over terminal management. */ extern void rl_prep_terminal (), rl_deprep_terminal (); --- 55,60 ---- *************** prepare_terminal_settings (meta_flag, ot *** 260,266 **** int meta_flag; TIOTYPE otio, *tiop; { - #if !defined (__GO32__) readline_echoing_p = (otio.sgttyb.sg_flags & ECHO); /* Copy the original settings to the structure we're going to use for --- 255,260 ---- *************** prepare_terminal_settings (meta_flag, ot *** 326,332 **** tiop->ltchars.t_dsuspc = -1; /* C-y */ tiop->ltchars.t_lnextc = -1; /* C-v */ #endif /* TIOCGLTC */ - #endif /* !__GO32__ */ } #else /* !defined (NEW_TTY_DRIVER) */ --- 320,325 ---- *************** void *** 521,527 **** rl_prep_terminal (meta_flag) int meta_flag; { - #if !defined (__GO32__) int tty; TIOTYPE tio; --- 514,519 ---- *************** rl_prep_terminal (meta_flag) *** 556,569 **** terminal_prepped = 1; release_sigint (); - #endif /* !__GO32__ */ } /* Restore the terminal's normal settings and modes. */ void rl_deprep_terminal () { - #if !defined (__GO32__) int tty; if (!terminal_prepped) --- 548,559 ---- *************** rl_deprep_terminal () *** 588,594 **** terminal_prepped = 0; release_sigint (); - #endif /* !__GO32__ */ } /* **************************************************************** */ --- 578,583 ---- *** readline/signals.c~0 Tue Dec 22 21:53:32 1998 --- readline/signals.c Thu May 20 19:20:44 1999 *************** *** 40,48 **** # include #endif /* GWINSZ_IN_SYS_IOCTL */ ! #if defined (__GO32__) ! # undef HANDLE_SIGNALS ! #endif /* __GO32__ */ #if defined (HANDLE_SIGNALS) /* Some standard library routines. */ --- 40,48 ---- # include #endif /* GWINSZ_IN_SYS_IOCTL */ ! #ifdef __DJGPP__ ! # include ! #endif #if defined (HANDLE_SIGNALS) /* Some standard library routines. */ *** readline/display.c~1 Mon May 17 20:05:18 1999 --- readline/display.c Sat May 22 18:51:58 1999 *************** *** 44,52 **** #if defined (__GO32__) # include # include - # if defined (__DJGPP__) - # include - # endif /* __DJGPP__ */ #endif /* __GO32__ */ /* System-specific feature definitions and include files. */ --- 44,49 ---- *************** _rl_move_vert (to) *** 1110,1115 **** --- 1107,1113 ---- { int row, col; + fflush (rl_outstream); /* make sure the cursor pos is current! */ ScreenGetCursor (&row, &col); ScreenSetCursor ((row + to - _rl_last_v_pos), col); } *************** void *** 1336,1360 **** _rl_clear_to_eol (count) int count; { ! #if defined (__GO32__) ! if (!count) ! { ! int ncols = ScreenCols (); ! unsigned short fill = ' ' | (ScreenAttrib << 8); ! int row, col, len; ! unsigned short *line_buf; ! int i; ! ! ScreenGetCursor (&row, &col); ! len = (ncols - col) * sizeof (*line_buf); ! line_buf = alloca (len); ! for (i = 0; i < ncols - col; i++) ! line_buf[i] = fill; ! ! dosmemput (line_buf, len, ScreenPrimary + (ncols * row + col) * 2); ! } ! else ! #else /* !__GO32__ */ if (term_clreol) tputs (term_clreol, 1, _rl_output_character_function); else if (count) --- 1334,1340 ---- _rl_clear_to_eol (count) int count; { ! #ifndef __GO32__ if (term_clreol) tputs (term_clreol, 1, _rl_output_character_function); else if (count) *************** void *** 1380,1386 **** _rl_clear_screen () { #if defined (__GO32__) ! ScreenClear (); ScreenSetCursor (0, 0); /* term_clrpag is "cl" which homes the cursor */ #else /* !__GO32__ */ if (term_clrpag) --- 1360,1366 ---- _rl_clear_screen () { #if defined (__GO32__) ! ScreenClear (); /* FIXME: only works in text modes */ ScreenSetCursor (0, 0); /* term_clrpag is "cl" which homes the cursor */ #else /* !__GO32__ */ if (term_clrpag) *************** insert_some_chars (string, count) *** 1396,1416 **** char *string; int count; { ! #if defined (__GO32__) ! int row, col, width; ! unsigned row_start; ! ! ScreenGetCursor (&row, &col); ! width = ScreenCols (); ! row_start = ScreenPrimary + row * width * 2; ! movedata (_dos_ds, row_start + 2 * col, ! _dos_ds, row_start + 2 * (col + count), ! 2 * (width - col - count)); ! ! /* Place the text on the screen. */ ! _rl_output_some_chars (string, count); ! #else /* !_GO32 */ ! /* If IC is defined, then we do not have to "enter" insert mode. */ if (term_IC) { --- 1376,1382 ---- char *string; int count; { ! #ifndef __GO32__ /* If IC is defined, then we do not have to "enter" insert mode. */ if (term_IC) { *************** static void *** 1451,1475 **** delete_chars (count) int count; { ! #if defined (__GO32__) ! int row, col, width; ! unsigned row_start; ! unsigned short *blank_fill = alloca (count * sizeof (*blank_fill)); ! unsigned short fill_val = ' ' | (ScreenAttrib << 8); ! int i; ! ! for (i = 0; i < count; i++) ! blank_fill[i] = fill_val; ! ScreenGetCursor (&row, &col); ! width = ScreenCols (); ! row_start = ScreenPrimary + row * width * 2; ! movedata (_dos_ds, row_start + 2 * (col + count), ! _dos_ds, row_start + 2 * col, ! 2 * (width - col - count)); ! dosmemput (blank_fill, count * 2, row_start + 2 * (width - count)); ! ! #else /* !_GO32 */ ! if (count > screenwidth) /* XXX */ return; --- 1417,1423 ---- delete_chars (count) int count; { ! #ifndef __GO32__ if (count > screenwidth) /* XXX */ return; *** readline/complete.c~0 Tue Dec 22 21:53:32 1998 --- readline/complete.c Wed Jun 2 22:53:00 1999 *************** username_completion_function (text, stat *** 1361,1369 **** int state; char *text; { ! #if defined (__GO32__) || defined (__WIN32__) return (char *)NULL; ! #else /* !__GO32__ */ static char *username = (char *)NULL; static struct passwd *entry; static int namelen, first_char, first_char_loc; --- 1361,1369 ---- int state; char *text; { ! #if defined (__WIN32__) return (char *)NULL; ! #else /* !__WIN32__ */ static char *username = (char *)NULL; static struct passwd *entry; static int namelen, first_char, first_char_loc; *************** username_completion_function (text, stat *** 1406,1412 **** return (value); } ! #endif /* !__GO32__ */ } /* Okay, now we write the entry_function for filename completion. In the --- 1406,1412 ---- return (value); } ! #endif /* !__WIN32__ */ } /* Okay, now we write the entry_function for filename completion. In the *************** filename_completion_function (text, stat *** 1453,1458 **** --- 1453,1466 ---- strcpy (filename, ++temp); *temp = '\0'; } + #if defined (__WIN32__) || defined (__MSDOS__) + /* Handle the drive-relative names "d:foo/bar". */ + else if (dirname[1] == ':') + { + strcpy (filename, dirname + 2); + dirname[2] = '\0'; + } + #endif else { dirname[0] = '.'; *** readline/bind.c~0 Tue Dec 22 21:53:30 1998 --- readline/bind.c Thu Jun 3 18:58:04 1999 *************** extern int errno; *** 62,67 **** --- 62,71 ---- extern char *strchr (), *strrchr (); #endif /* !strchr && !__STDC__ */ + #ifndef O_BINARY + # define O_BINARY 0 + #endif + extern int _rl_horizontal_scroll_mode; extern int _rl_mark_modified_lines; extern int _rl_bell_preference; *************** _rl_read_file (filename, sizep) *** 642,648 **** char *buffer; int i, file; ! if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY, 0666)) < 0) return ((char *)NULL); file_size = (size_t)finfo.st_size; --- 646,652 ---- char *buffer; int i, file; ! if ((stat (filename, &finfo) < 0) || (file = open (filename, O_RDONLY|O_BINARY, 0666)) < 0) return ((char *)NULL); file_size = (size_t)finfo.st_size; *************** _rl_read_file (filename, sizep) *** 670,675 **** --- 674,703 ---- } buffer[file_size] = '\0'; + + #if O_BINARY + { + /* Systems which distinguish between text and binary files need + to strip the CR characters before each Newline, otherwise the + parsing functions won't work. */ + char *s, *d; + size_t removed = 0; + + for (s = buffer, d = buffer; s < buffer + file_size; s++) + { + if (removed) + *d = *s; + if (*s != '\r' || s[1] != '\n') + d++; + else + removed++; + } + + file_size -= removed; + buffer[file_size] = '\0'; + } + #endif + if (sizep) *sizep = file_size; return (buffer); *************** rl_re_read_init_file (count, ignore) *** 691,696 **** --- 719,725 ---- 1. the filename used for the previous call 2. the value of the shell variable `INPUTRC' 3. ~/.inputrc + 4. (for __MSDOS__ only) ~/_inputrc If the file existed and could be opened and read, 0 is returned, otherwise errno is returned. */ int *************** rl_read_init_file (filename) *** 710,715 **** --- 739,758 ---- if (*filename == 0) filename = DEFAULT_INPUTRC; + #ifdef __MSDOS__ + { + /* DOS doesn't allow leading dots in file names. If the original + name fails (it could work if we are on Windows), fall back to + ~/_inputrc. */ + int retval = _rl_read_init_file (filename, 0); + + if (retval == 0) + return retval; + else if (strcmp (filename, "~/.inputrc") == 0) + filename = "~/_inputrc"; + } + #endif + return (_rl_read_init_file (filename, 0)); } *** readline/histfile.c~0 Mon Dec 21 20:06:30 1998 --- readline/histfile.c Sat Jun 5 16:11:48 1999 *************** read_history_range (filename, from, to) *** 140,145 **** --- 140,154 ---- input = history_filename (filename); file = open (input, O_RDONLY|O_BINARY, 0666); + #ifdef __MSDOS__ + /* MSDOS doesn't allow leading dots in file names. Try again + with the dot replaced by an underscore. */ + if (file < 0 && !filename) + { + input[strlen (input) - 8] = '_'; + file = open (input, O_RDONLY|O_BINARY, 0666); + } + #endif if ((file < 0) || (fstat (file, &finfo) == -1)) goto error_and_exit; *************** read_history_range (filename, from, to) *** 155,161 **** --- 164,177 ---- } buffer = xmalloc (file_size + 1); + #ifdef __MSDOS__ + /* The actual number read might be smaller, due to CRs being + stripped. */ + file_size = read (file, buffer, file_size); + if (file_size < 0) + #else if (read (file, buffer, file_size) != file_size) + #endif { error_and_exit: if (file >= 0) *************** history_truncate_file (fname, lines) *** 229,234 **** --- 245,260 ---- filename = history_filename (fname); file = open (filename, O_RDONLY|O_BINARY, 0666); + #ifdef __MSDOS__ + /* MSDOS doesn't allow leading dots in file names. Try again + with the dot replaced by an underscore. */ + if (file < 0 && !fname) + { + filename[strlen (filename) - 8] = '_'; + file = open (filename, O_RDONLY|O_BINARY, 0666); + } + #endif + if (file == -1 || fstat (file, &finfo) == -1) goto truncate_exit; *************** history_truncate_file (fname, lines) *** 275,281 **** truncate to. */ if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { ! write (file, buffer + i, file_size - i); close (file); } --- 301,307 ---- truncate to. */ if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) { ! write (file, buffer + i, chars_read - i); close (file); } *************** history_do_write (filename, nelements, o *** 302,311 **** --- 328,353 ---- mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; output = history_filename (filename); + if ((file = open (output, mode, 0600)) == -1) { + #ifdef __MSDOS__ + /* MSDOS doesn't allow leading dots in file names. If this is + the default file name, try again with the dot replaced by an + underscore. */ + if (!filename) + { + output[strlen (output) - 8] = '_'; + if ((file = open (output, mode, 0600)) == -1) + { + FREE (output); + return (errno); + } + } + #else FREE (output); return (errno); + #endif } if (nelements > history_length) *** gdb/top.c~3 Sat May 22 13:01:52 1999 --- gdb/top.c Sat Jun 5 16:38:46 1999 *************** init_history() *** 3466,3472 **** --- 3466,3477 ---- /* We include the current directory so that if the user changes directories the file written will be the same as the one that was read. */ + #ifdef __MSDOS__ + /* No leading dots in file names are allowed on MSDOS. */ + history_filename = concat (current_directory, "/_gdb_history", NULL); + #else history_filename = concat (current_directory, "/.gdb_history", NULL); + #endif } read_history (history_filename); }