To: vim-dev@vim.org Subject: Patch 6.2.223 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.223 Problem: Cscope: Avoid a hang when cscope waits for a response while Vim waits for a prompt. Error messages from Cscope mess up the display. Solution: Detect the hit-enter message and respond by sending a return character to cscope. (Gary Johnson) Use EMSG() and strerror() when possible. Replace perror() with PERROR() everywhere, add emsg3(). Files: src/diff.c, src/if_cscope.c, src/integration.c, src/message.c, src/proto/message.pro, src/misc2.c, src/netbeans.c, src/vim.h *** ../vim-6.2.222/src/diff.c Sun Jan 18 20:58:01 2004 --- src/diff.c Sun Feb 1 15:01:19 2004 *************** *** 130,136 **** return; } ! EMSG2(_("E96: Can not diff more than %ld buffers"), DB_COUNT); } /* --- 130,136 ---- return; } ! EMSGN(_("E96: Can not diff more than %ld buffers"), DB_COUNT); } /* *** ../vim-6.2.222/src/if_cscope.c Wed Sep 10 21:35:55 2003 --- src/if_cscope.c Sun Feb 1 15:23:43 2004 *************** *** 754,764 **** err_save = dup(STDERR_FILENO); #endif if (dup2(to_cs[0], STDIN_FILENO) == -1) ! perror("cs_create_connection 1"); if (dup2(from_cs[1], STDOUT_FILENO) == -1) ! perror("cs_create_connection 2"); if (dup2(from_cs[1], STDERR_FILENO) == -1) ! perror("cs_create_connection 3"); /* close unused */ #if defined(UNIX) --- 754,764 ---- err_save = dup(STDERR_FILENO); #endif if (dup2(to_cs[0], STDIN_FILENO) == -1) ! PERROR("cs_create_connection 1"); if (dup2(from_cs[1], STDOUT_FILENO) == -1) ! PERROR("cs_create_connection 2"); if (dup2(from_cs[1], STDERR_FILENO) == -1) ! PERROR("cs_create_connection 3"); /* close unused */ #if defined(UNIX) *************** *** 839,845 **** #if defined(UNIX) if (execl("/bin/sh", "sh", "-c", cmd, NULL) == -1) ! perror(_("cs_create_connection exec failed")); exit(127); /* NOTREACHED */ --- 839,845 ---- #if defined(UNIX) if (execl("/bin/sh", "sh", "-c", cmd, NULL) == -1) ! PERROR(_("cs_create_connection exec failed")); exit(127); /* NOTREACHED */ *************** *** 889,895 **** # endif if (ph == -1) { ! perror(_("cs_create_connection exec failed")); (void)EMSG(_("E623: Could not spawn cscope process")); goto err_closing; } --- 889,895 ---- # endif if (ph == -1) { ! PERROR(_("cs_create_connection exec failed")); (void)EMSG(_("E623: Could not spawn cscope process")); goto err_closing; } *************** *** 903,911 **** * reopen as streams. */ if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) ! perror(_("cs_create_connection: fdopen for to_fp failed")); if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) ! perror(_("cs_create_connection: fdopen for fr_fp failed")); #if defined(UNIX) /* close unused */ --- 903,911 ---- * reopen as streams. */ if ((csinfo[i].to_fp = fdopen(to_cs[1], "w")) == NULL) ! PERROR(_("cs_create_connection: fdopen for to_fp failed")); if ((csinfo[i].fr_fp = fdopen(from_cs[0], "r")) == NULL) ! PERROR(_("cs_create_connection: fdopen for fr_fp failed")); #if defined(UNIX) /* close unused */ *************** *** 1974,2027 **** int ch; char *buf = NULL; /* buffer for possible error message from cscope */ int bufpos = 0; ! static char *cs_emsg = N_("E609: Cscope error: %s"); ! /* maximum allowed len for Cscope error message */ ! int maxlen = IOSIZE - strlen(_(cs_emsg)); for (;;) { while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0]) ! /* if verbose, have space and char is printable */ ! if (p_csverbose && bufpos < maxlen - 1 && vim_isprintc(ch)) { if (buf == NULL) /* lazy buffer allocation */ buf = (char *)alloc(maxlen); ! ! if (buf != NULL) /* append character to a string */ { buf[bufpos++] = ch; buf[bufpos] = NUL; } } ! if (ch == EOF) { ! perror("cs_read_prompt EOF(1)"); ! if (buf != NULL && buf[0] != NUL) ! (void)EMSG2(_(cs_emsg), buf); ! else if (p_csverbose) ! cs_reading_emsg(i); /* don't have additional information */ ! cs_release_csp(i, TRUE); ! vim_free(buf); ! return CSCOPE_FAILURE; ! } ! ch = getc(csinfo[i].fr_fp); ! if (ch == EOF) ! perror("cs_read_prompt EOF(2)"); ! if (ch != CSCOPE_PROMPT[1]) ! continue; - ch = getc(csinfo[i].fr_fp); if (ch == EOF) ! perror("cs_read_prompt EOF(3)"); ! if (ch != CSCOPE_PROMPT[2]) ! continue; ! break; } vim_free(buf); return CSCOPE_SUCCESS; ! } /* cs_read_prompt */ /* --- 1974,2053 ---- int ch; char *buf = NULL; /* buffer for possible error message from cscope */ int bufpos = 0; ! char *cs_emsg; ! int maxlen; ! static char *eprompt = "Press the RETURN key to continue:"; ! int epromptlen = strlen(eprompt); ! int n; ! ! cs_emsg = _("E609: Cscope error: %s"); ! /* compute maximum allowed len for Cscope error message */ ! maxlen = (int)(IOSIZE - strlen(cs_emsg)); for (;;) { while ((ch = getc(csinfo[i].fr_fp)) != EOF && ch != CSCOPE_PROMPT[0]) ! /* if there is room and char is printable */ ! if (bufpos < maxlen - 1 && vim_isprintc(ch)) { if (buf == NULL) /* lazy buffer allocation */ buf = (char *)alloc(maxlen); ! if (buf != NULL) { + /* append character to the message */ buf[bufpos++] = ch; buf[bufpos] = NUL; + if (bufpos >= epromptlen + && strcmp(&buf[bufpos - epromptlen], eprompt) == 0) + { + /* remove eprompt from buf */ + buf[bufpos - epromptlen] = NUL; + + /* print message to user */ + (void)EMSG2(cs_emsg, buf); + + /* send RETURN to cscope */ + (void)putc('\n', csinfo[i].to_fp); + (void)fflush(csinfo[i].to_fp); + + /* clear buf */ + bufpos = 0; + buf[bufpos] = NUL; + } } } ! for (n = 0; n < (int)strlen(CSCOPE_PROMPT); ++n) { ! if (n > 0) ! ch = getc(csinfo[i].fr_fp); ! if (ch == EOF) ! { ! PERROR("cs_read_prompt EOF"); ! if (buf != NULL && buf[0] != NUL) ! (void)EMSG2(cs_emsg, buf); ! else if (p_csverbose) ! cs_reading_emsg(i); /* don't have additional information */ ! cs_release_csp(i, TRUE); ! vim_free(buf); ! return CSCOPE_FAILURE; ! } ! if (ch != CSCOPE_PROMPT[n]) ! { ! ch = EOF; ! break; ! } ! } if (ch == EOF) ! continue; /* didn't find the prompt */ ! break; /* did find the prompt */ } + vim_free(buf); return CSCOPE_SUCCESS; ! } /* *** ../vim-6.2.222/src/integration.c Sun Jul 27 14:16:53 2003 --- src/integration.c Sun Feb 1 15:20:40 2004 *************** *** 648,654 **** port = atoi(address); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! perror(NOCATGETS("workshop_connect")); return; } --- 648,654 ---- port = atoi(address); if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! PERROR(NOCATGETS("workshop_connect")); return; } *************** *** 658,671 **** server.sin_family = AF_INET; server.sin_port = port; if ((host = gethostbyname(NOCATGETS("localhost"))) == NULL) { ! perror(NOCATGETS("gethostbyname")); sd = -1; return; } memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! perror(NOCATGETS("workshop_connect")); return; } --- 658,671 ---- server.sin_family = AF_INET; server.sin_port = port; if ((host = gethostbyname(NOCATGETS("localhost"))) == NULL) { ! PERROR(NOCATGETS("gethostbyname")); sd = -1; return; } memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! PERROR(NOCATGETS("workshop_connect")); return; } *************** *** 678,700 **** close(sd); #ifdef INET_SOCKETS if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! perror(NOCATGETS("workshop_connect")); return; } #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! perror(NOCATGETS("workshop_connect")); return; } #endif if (connect(sd, (struct sockaddr *)&server, sizeof(server))) { ! perror(NOCATGETS("workshop_connect")); return; } } else { ! perror(NOCATGETS("workshop_connect")); return; } } --- 678,700 ---- close(sd); #ifdef INET_SOCKETS if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! PERROR(NOCATGETS("workshop_connect")); return; } #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! PERROR(NOCATGETS("workshop_connect")); return; } #endif if (connect(sd, (struct sockaddr *)&server, sizeof(server))) { ! PERROR(NOCATGETS("workshop_connect")); return; } } else { ! PERROR(NOCATGETS("workshop_connect")); return; } } *** ../vim-6.2.222/src/message.c Sun Jan 25 20:28:03 2004 --- src/message.c Sun Feb 1 15:14:08 2004 *************** *** 554,563 **** --- 554,576 ---- return msg_attr(s, attr); } + /* + * Print an error message with one "%s" and one string argument. + */ int emsg2(s, a1) char_u *s, *a1; { + return emsg3(s, a1, NULL); + } + + /* + * Print an error message with one or two "%s" and one or two string arguments. + */ + int + emsg3(s, a1, a2) + char_u *s, *a1, *a2; + { if ((emsg_off > 0 && *p_debug == NUL) #ifdef FEAT_EVAL || emsg_skip > 0 *************** *** 568,582 **** /* Check for NULL strings (just in case) */ if (a1 == NULL) a1 = (char_u *)"[NULL]"; ! /* Check for very long strings (can happen with ":help ^A"). ! * Careful, the argument could actually be a long. */ ! if (STRLEN(s) + (strstr((char *)s, "%s") != NULL ? STRLEN(a1) : 20) ! >= (size_t)IOSIZE) ! a1 = (char_u *)_("[string too long]"); ! sprintf((char *)IObuff, (char *)s, (char *)a1); return emsg(IObuff); } int emsgn(s, n) char_u *s; --- 581,600 ---- /* Check for NULL strings (just in case) */ if (a1 == NULL) a1 = (char_u *)"[NULL]"; ! if (a2 == NULL) ! a2 = (char_u *)"[NULL]"; ! ! /* Check for very long strings (can happen with ":help ^A"). */ ! if (STRLEN(s) + STRLEN(a1) + STRLEN(a2) >= (size_t)IOSIZE) ! a1 = a2 = (char_u *)_("[string too long]"); ! ! sprintf((char *)IObuff, (char *)s, (char *)a1, (char *)a2); return emsg(IObuff); } + /* + * Print an error message with one "%ld" and one long int argument. + */ int emsgn(s, n) char_u *s; *** ../vim-6.2.222/src/proto/message.pro Sun Jun 1 12:26:14 2003 --- src/proto/message.pro Sun Feb 1 15:23:42 2004 *************** *** 6,11 **** --- 6,12 ---- void trunc_string __ARGS((char_u *s, char_u *buf, int room)); int emsg __ARGS((char_u *s)); int emsg2 __ARGS((char_u *s, char_u *a1)); + int emsg3 __ARGS((char_u *s, char_u *a1, char_u *a2)); int emsgn __ARGS((char_u *s, long n)); char_u *msg_trunc_attr __ARGS((char_u *s, int force, int attr)); char_u *msg_may_trunc __ARGS((int force, char_u *s)); *** ../vim-6.2.222/src/misc2.c Sun Jan 18 20:58:01 2004 --- src/misc2.c Sun Feb 1 15:26:21 2004 *************** *** 896,902 **** { /* Don't hide this message */ emsg_silent = 0; ! EMSG2(_("E342: Out of memory! (allocating %lu bytes)"), size); did_outofmem_msg = TRUE; } } --- 896,902 ---- { /* Don't hide this message */ emsg_silent = 0; ! EMSGN(_("E342: Out of memory! (allocating %lu bytes)"), size); did_outofmem_msg = TRUE; } } *** ../vim-6.2.222/src/netbeans.c Fri Jan 30 21:03:16 2004 --- src/netbeans.c Sun Feb 1 15:21:15 2004 *************** *** 272,278 **** if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! perror("socket() in netbeans_connect()"); return; } --- 272,278 ---- if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! PERROR("socket() in netbeans_connect()"); return; } *************** *** 289,295 **** sd = open(hostname, O_RDONLY); return; } ! perror("gethostbyname() in netbeans_connect()"); sd = -1; return; } --- 289,295 ---- sd = open(hostname, O_RDONLY); return; } ! PERROR("gethostbyname() in netbeans_connect()"); sd = -1; return; } *************** *** 297,303 **** #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! perror("socket()"); return; } --- 297,303 ---- #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! PERROR("socket()"); return; } *************** *** 314,326 **** #ifdef INET_SOCKETS if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! perror("socket()#2 in netbeans_connect()"); return; } #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! perror("socket()#2 in netbeans_connect()"); return; } #endif --- 314,326 ---- #ifdef INET_SOCKETS if ((sd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { ! PERROR("socket()#2 in netbeans_connect()"); return; } #else if ((sd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { ! PERROR("socket()#2 in netbeans_connect()"); return; } #endif *************** *** 343,349 **** if (!success) { /* Get here when the server can't be found. */ ! perror(_("Cannot connect to Netbeans #2")); getout(1); } } --- 343,349 ---- if (!success) { /* Get here when the server can't be found. */ ! PERROR(_("Cannot connect to Netbeans #2")); getout(1); } } *************** *** 351,357 **** } else { ! perror(_("Cannot connect to Netbeans")); getout(1); } } --- 351,357 ---- } else { ! PERROR(_("Cannot connect to Netbeans")); getout(1); } } *************** *** 630,636 **** netbeans_disconnect(); nbdebug(("messageFromNetbeans: Error in read() from socket\n")); if (len < 0) ! perror(_("read from Netbeans socket")); return; /* don't try to parse it */; } --- 630,636 ---- netbeans_disconnect(); nbdebug(("messageFromNetbeans: Error in read() from socket\n")); if (len < 0) ! PERROR(_("read from Netbeans socket")); return; /* don't try to parse it */; } *** ../vim-6.2.222/src/vim.h Wed Nov 5 10:32:28 2003 --- src/vim.h Sun Feb 1 15:17:21 2004 *************** *** 1242,1247 **** --- 1242,1255 ---- #define MSG_PUTS_LONG(s) msg_puts_long((char_u *)(s)) #define MSG_PUTS_LONG_ATTR(s, a) msg_puts_long_attr((char_u *)(s), (a)) + /* Prefer using emsg3(), because perror() may send the output to the wrong + * destination and mess up the screen. */ + #ifdef HAVE_STRERROR + # define PERROR(msg) (void)emsg3((char_u *)"%s: %s", (char_u *)msg, (char_u *)strerror(errno)) + #else + # define PERROR(msg) perror(msg) + #endif + typedef long linenr_T; /* line number type */ typedef unsigned colnr_T; /* column number type */ typedef unsigned short disptick_T; /* display tick type */ *** ../vim-6.2.222/src/version.c Mon Feb 2 10:03:01 2004 --- src/version.c Mon Feb 2 12:47:46 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 223, /**/ -- hundred-and-one symptoms of being an internet addict: 25. You believe nothing looks sexier than a man in boxer shorts illuminated only by a 17" inch svga monitor. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///