unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#51171: 27.2; `forward-word' w/arg bug in narrowed buffer
@ 2021-10-13  0:17 Ian Nehera
  2021-10-14  9:22 ` Eli Zaretskii
  0 siblings, 1 reply; 3+ messages in thread
From: Ian Nehera @ 2021-10-13  0:17 UTC (permalink / raw)
  To: 51171

[-- Attachment #1: Type: text/plain, Size: 63 bytes --]

Hi, I found a bug relating to subword mode in narrowed buffers.

[-- Attachment #2: dcl.c --]
[-- Type: application/octet-stream, Size: 5740 bytes --]

#include <stdio.h>
#include <string.h>
#include <ctype.h>

#define MAXTOKEN 100             /* can't go below 3 */
#define MAXOUTPUT 1000           /* should always be >= MAXTOKEN */

enum { NAME, PARENS, BRACKETS } TokenType;
enum { OK, ERROR };

static const char *Typelist[] = {
    "char",
    "int",
    "short",
    "long",
    "unsigned",
    "float",
    "double",
    "void",
    NULL
};

static char Name[MAXTOKEN], Output[MAXOUTPUT], Token[MAXTOKEN];
static int OutSpc = MAXOUTPUT;

void undeclaration(void);
void declaration(void);

int dcl(void);
int dirdcl(void);

void outputCat(const char *s);
void flushline(void);
int gettoken(void);

int main(const int argc, const char *argv[])
{
    if (argc > 1 && strcmp(argv[1], "--undcl") == 0)
        undeclaration();
    else
        declaration();
    return 0;
}

void undeclaration(void)
{
    char type, temp[MAXOUTPUT];
    int ispointer = 0;

    while (gettoken() != EOF) {
        strcpy(Output, Token);
        OutSpc = MAXOUTPUT - strlen(Token);
        while ((type = gettoken()) != '\n') {
            if (type == PARENS || type == BRACKETS) {
                if (ispointer) {
                    OutSpc -= snprintf(temp, MAXOUTPUT, "(%s)%s", Output, Token); /* C99 feature */
                    strcpy(Output, temp);
                    ispointer = 0;
                } else {
                    outputCat(Token);
                }
            } else if (type == '*') {
                snprintf(temp, MAXOUTPUT, "*%s", Output);
                strcpy(Output, temp);
                ispointer = 1;
            } else if (type == NAME) {
                snprintf(temp, MAXOUTPUT, "%s %s", Token, Output);
                strcpy(Output, temp);
                ispointer = 0;
            } else {
                printf("ERROR: Invalid input at %s\n", Token);
            }
        }
        printf("%s\n", Output);
        ispointer = 0;          /* reset for next line of input */
    }
}

char gettype(char *s);

void declaration(void)
{
    char datatype[MAXTOKEN];

    while (gettype(datatype) != EOF) {
        Output[0] = '\0';
        if (dcl() == ERROR) {
            flushline();
        } else if (TokenType != '\n' && TokenType != ',') {
            printf("ERROR: Syntax error for %s.\n", datatype);
            flushline();
        } else {
            printf("%s: %s %s\n", Name, Output, datatype);
            Token[0] = '\0';
        }
    }
}

int dcl(void)
{
    int ns = 0;

    while (gettoken() == '*')
        ++ns;
    if (dirdcl() == ERROR)
        return ERROR;
    while (ns-- > 0)
        outputCat(" pointer to");

    return OK;
}

int dirdcl(void)
{
    if (TokenType == '(') {
        if (dcl() == ERROR) {
            return ERROR;
        }
        if (TokenType != ')') {
            printf("ERROR: Closing ')' paren missing.\n");
            return ERROR;
        }
    } else if (TokenType == NAME) {
        strcpy(Name, Token);
    } else {
        printf("ERROR: Expected name or (dcl).\n");
        return ERROR;
    }

    while (gettoken() == PARENS || TokenType == BRACKETS) {
        if (TokenType == PARENS) {
            outputCat(" function returning");
        } else {
            outputCat(" array");
            strcat(Output, Token);
            outputCat(" of");
        }
    }

    return OK;
}

char getch(void);
void ungetch(const char c);

int gettoken(void)
{
    char c, *p = Token;

    while (isblank(c = getch())) /* C99 feature */
        ;
    if (c == '(') {
        if ((c = getch()) == ')') {
            strcpy(Token, "()");
            TokenType = PARENS;
        } else {
            ungetch(c);
            TokenType = '(';
        }
    } else if (c == '[') {
        for (*p++ = c; (*p++ = getch()) != ']' && p-Token < MAXTOKEN-1; )
            ;
        *p = '\0';
        TokenType = BRACKETS;
    } else if (isalpha(c) || c == '_') {
        for (*p++ = c; (isalnum(c = getch()) || c == '_') && p-Token < MAXTOKEN-1; ) {
            *p++ = c;
        }
        *p = '\0';
        ungetch(c);
        TokenType = NAME;
    } else {
        TokenType = c;
    }

    return TokenType;
}

char gettype(char *s)
{
    static const char *last, *start, **type;
    static char c;

    while (isblank(c = getch()))
        ;

    last = start = s;
    while (isalpha(c) || c == '_') {
        last = s;
        for (*s++ = c; (isalnum(c = getch()) || c == '_') && s-start < MAXTOKEN-1; ) {
            *s++ = c;
        }
        if (isblank(c) && s-start < MAXTOKEN-1) {
            *s++ = ' ';     /* no point in printing a tab char */
            while (isblank(c = getch()))
                ;
        }
    }
    ungetch(c);
    if (*(s-1) == ' ')      /* should only be one 'space' at most */
        --s;
    *s = '\0';

    if (last != start) {
        for (type = Typelist; *type != NULL && strcmp(*type, last); ++type)
            ;
        if (*type == NULL) {
            do {
                ungetch(*--s);
            } while (s >= last);
            *s = '\0';
        }
    }

    TokenType = '\n';
    return c;
}

void outputCat(const char *s)
{
    if ((OutSpc -= strlen(s)) > 0) {
        strcat(Output, s);
    } else {
        printf("ERROR: Not enough space in Output[] to add:\n\
\"%s\"\n", s);
    }
}

void flushline(void)
{
    static char c;

    /* flush both buffer[] and stdin */
    while ((c = getch()) != '\n' && c != EOF)
        ;
    if (c == EOF)
        ungetch(c);
}

#define BUFFER 1000

char buffer[BUFFER];
char *bp = buffer;

char getch(void)
{
    return (bp > buffer) ? *--bp : getchar();
}

void ungetch(const char c)
{
    if (bp - buffer < BUFFER)
        *bp++ = c;
    else
        printf("ERROR: ungetch(); not enough room to unget '%c'.\n");
}

[-- Attachment #3: Type: text/plain, Size: 4548 bytes --]



To reproduce from 'emacs -Q /path/to/dcl.c’ (file attached):
   1. M-x `subword-mode' (side question: should C-c C-w still use the
      obsolete alias `c-subword-mode'?).
   2. Navigate to the function 'int dirdcl(void)' and use
      `narrow-to-defun' (C-x n d).
   3. From the top of the buffer, use `forward-word' with an arg greater
      than 1 (like C-u 2 M-f).
   4. Repeat this with C-x z z z z... until you get an error around the
      start of the while loop (2nd to last message in list below).
   5. Moving point forward then trying the same command again will yield
       the last message with a number greater than `point-max' (5741).

Other notes:
      - The bug dissapears with a widened buffer or when narrowing to
        earlier functions.
      - `backward-word’ doesn’t seem to have the same problem.
      - I'm reporting this from OSX 10.14.6 (homebrew), but it also occurs on
        Arch Linux (emacs being installed from the standard pacman repos).

Thanks,
Ian

————————————————————————————————————————————————

In GNU Emacs 27.2 (build 1, x86_64-apple-darwin18.7.0, NS appkit-1671.60 Version 10.14.6 (Build 18G95))
 of 2021-03-27 built on builder10-14.porkrind.org
Windowing system distributor 'Apple', version 10.3.1671
System Description:  Mac OS X 10.14.6

Recent messages:
For information about GNU Emacs and the GNU system, type C-h C-a.
Subword mode enabled in current buffer
You can run the command ‘subword-mode’ with M-x sub-mo RET
Subword mode enabled in current buffer
Mark saved where search started
Repeating command 2 forward-word [22 times]
funcall-interactively: Error in syntax_table logic for to-the-end intervals
funcall-interactively: Point 5751 after end of properties

Configured using:
 'configure --with-ns '--enable-locallisppath=/Library/Application
 Support/Emacs/${version}/site-lisp:/Library/Application
 Support/Emacs/site-lisp' --with-modules'

Configured features:
NOTIFY KQUEUE ACL GNUTLS LIBXML2 ZLIB TOOLKIT_SCROLL_BARS NS MODULES
THREADS JSON PDUMPER GMP

Important settings:
  value of $LANG: en_CA.UTF-8
  locale-coding-system: utf-8-unix

Major mode: C/*l

Minor modes in effect:
  subword-mode: t
  tooltip-mode: t
  global-eldoc-mode: t
  electric-indent-mode: t
  mouse-wheel-mode: t
  tool-bar-mode: t
  menu-bar-mode: t
  file-name-shadow-mode: t
  global-font-lock-mode: t
  font-lock-mode: t
  blink-cursor-mode: t
  auto-composition-mode: t
  auto-encryption-mode: t
  auto-compression-mode: t
  line-number-mode: t
  transient-mark-mode: t
  abbrev-mode: t

Load-path shadows:
None found.

Features:
(shadow sort mail-extr emacsbug message rmc puny dired dired-loaddefs
format-spec rfc822 mml mml-sec password-cache epa derived epg epg-config
gnus-util rmail rmail-loaddefs text-property-search time-date subr-x seq
byte-opt gv bytecomp byte-compile cconv mm-decode mm-bodies mm-encode
mail-parse rfc2231 mailabbrev gmm-utils mailheader sendmail rfc2047
rfc2045 ietf-drums mm-util mail-prsvr mail-utils repeat misearch
multi-isearch cap-words superword subword cc-mode cc-fonts easymenu
cc-guess cc-menus cc-cmds cc-styles cc-align cc-engine cc-vars cc-defs
cl-loaddefs cl-lib tooltip eldoc electric uniquify ediff-hook vc-hooks
lisp-float-type mwheel term/ns-win ns-win ucs-normalize mule-util
term/common-win tool-bar dnd fontset image regexp-opt fringe
tabulated-list replace newcomment text-mode elisp-mode lisp-mode
prog-mode register page tab-bar menu-bar rfn-eshadow isearch timer
select scroll-bar mouse jit-lock font-lock syntax facemenu font-core
term/tty-colors frame minibuffer cl-generic cham georgian utf-8-lang
misc-lang vietnamese tibetan thai tai-viet lao korean japanese eucjp-ms
cp51932 hebrew greek romanian slovak czech european ethiopic indian
cyrillic chinese composite charscript charprop case-table epa-hook
jka-cmpr-hook help simple abbrev obarray cl-preloaded nadvice loaddefs
button faces cus-face macroexp files text-properties overlay sha1 md5
base64 format env code-pages mule custom widget hashtable-print-readable
backquote threads kqueue cocoa ns multi-tty make-network-process emacs)

Memory information:
((conses 16 67774 7216)
 (symbols 48 8485 1)
 (strings 32 21588 2096)
 (string-bytes 1 819438)
 (vectors 16 12983)
 (vector-slots 8 159689 12408)
 (floats 8 21 47)
 (intervals 56 528 0)
 (buffers 1000 12))


^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#51171: 27.2; `forward-word' w/arg bug in narrowed buffer
  2021-10-13  0:17 bug#51171: 27.2; `forward-word' w/arg bug in narrowed buffer Ian Nehera
@ 2021-10-14  9:22 ` Eli Zaretskii
  2022-09-12 12:02   ` Lars Ingebrigtsen
  0 siblings, 1 reply; 3+ messages in thread
From: Eli Zaretskii @ 2021-10-14  9:22 UTC (permalink / raw)
  To: Ian Nehera, Stefan Monnier; +Cc: 51171

> From: Ian Nehera <delta29@shaw.ca>
> Date: Tue, 12 Oct 2021 17:17:14 -0700
> 
> To reproduce from 'emacs -Q /path/to/dcl.c’ (file attached):
>    1. M-x `subword-mode' (side question: should C-c C-w still use the
>       obsolete alias `c-subword-mode'?).
>    2. Navigate to the function 'int dirdcl(void)' and use
>       `narrow-to-defun' (C-x n d).
>    3. From the top of the buffer, use `forward-word' with an arg greater
>       than 1 (like C-u 2 M-f).
>    4. Repeat this with C-x z z z z... until you get an error around the
>       start of the while loop (2nd to last message in list below).
>    5. Moving point forward then trying the same command again will yield
>        the last message with a number greater than `point-max' (5741).
> 
> Other notes:
>       - The bug dissapears with a widened buffer or when narrowing to
>         earlier functions.
>       - `backward-word’ doesn’t seem to have the same problem.
>       - I'm reporting this from OSX 10.14.6 (homebrew), but it also occurs on
>         Arch Linux (emacs being installed from the standard pacman repos).

Stefan, any suggestions wrt this?





^ permalink raw reply	[flat|nested] 3+ messages in thread

* bug#51171: 27.2; `forward-word' w/arg bug in narrowed buffer
  2021-10-14  9:22 ` Eli Zaretskii
@ 2022-09-12 12:02   ` Lars Ingebrigtsen
  0 siblings, 0 replies; 3+ messages in thread
From: Lars Ingebrigtsen @ 2022-09-12 12:02 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: 51171, Stefan Monnier, Ian Nehera

Eli Zaretskii <eliz@gnu.org> writes:

>> To reproduce from 'emacs -Q /path/to/dcl.c’ (file attached):
>>    1. M-x `subword-mode' (side question: should C-c C-w still use the
>>       obsolete alias `c-subword-mode'?).
>>    2. Navigate to the function 'int dirdcl(void)' and use
>>       `narrow-to-defun' (C-x n d).
>>    3. From the top of the buffer, use `forward-word' with an arg greater
>>       than 1 (like C-u 2 M-f).
>>    4. Repeat this with C-x z z z z... until you get an error around the
>>       start of the while loop (2nd to last message in list below).
>>    5. Moving point forward then trying the same command again will yield
>>        the last message with a number greater than `point-max' (5741).
>> 
>> Other notes:
>>       - The bug dissapears with a widened buffer or when narrowing to
>>         earlier functions.
>>       - `backward-word’ doesn’t seem to have the same problem.
>>       - I'm reporting this from OSX 10.14.6 (homebrew), but it also occurs on
>>         Arch Linux (emacs being installed from the standard pacman repos).
>
> Stefan, any suggestions wrt this?

The backtrace is:

Debugger entered--Lisp error: (error "Error in syntax_table logic for to-the-end interva...")
  forward-word(2)
  funcall-interactively(forward-word 2)
  call-interactively(forward-word nil nil)

Slightly easier recipe:

Open that file, `M-x subword-mode', and then navigate to

    while (gettoken() == PARENS || TokenType == BRACKETS) {

`C-x n d', put point after BRACKETS and then say `M-2 M-f'.  Then you
get that error message.

Just `M-f' works fine.

I tried to narrow this down to a simpler file, but I was unable to -- it
seems like the error depends on lots of state in that specific file.





^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2022-09-12 12:02 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-13  0:17 bug#51171: 27.2; `forward-word' w/arg bug in narrowed buffer Ian Nehera
2021-10-14  9:22 ` Eli Zaretskii
2022-09-12 12:02   ` Lars Ingebrigtsen

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).