From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: fabrice nicol Newsgroups: gmane.emacs.bugs Subject: bug#47408: [PATCH] Etags support for Mercury -- fix explicit tags for existentially-quantified procedures Date: Thu, 17 Jun 2021 20:36:56 +0200 Message-ID: <768bbdf8-19a9-7401-65a0-9171678c006b@gmail.com> References: <46bb9128-8bf5-e24c-2172-1cbb4202ee1d@gmail.com> <83lf7c5t6z.fsf@gnu.org> <46a10b9f-91d7-63c4-1513-0af4743e0940@gmail.com> <83eed45omq.fsf@gnu.org> <83y2b8zrxa.fsf@gnu.org> <83wnqszphk.fsf@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------9455C4B7B967BD282768F775" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="17176"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.11.0 Cc: 47408@debbugs.gnu.org To: Eli Zaretskii Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Thu Jun 17 20:37:05 2021 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1ltwsy-0004Kk-Rm for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 17 Jun 2021 20:37:04 +0200 Original-Received: from localhost ([::1]:55120 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1ltwsx-0002gM-RK for geb-bug-gnu-emacs@m.gmane-mx.org; Thu, 17 Jun 2021 14:37:03 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:48602) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1ltwry-0001Vh-RS for bug-gnu-emacs@gnu.org; Thu, 17 Jun 2021 14:36:04 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:43602) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1ltwry-0008No-Fj for bug-gnu-emacs@gnu.org; Thu, 17 Jun 2021 14:36:02 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1ltwry-0002cW-AV for bug-gnu-emacs@gnu.org; Thu, 17 Jun 2021 14:36:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: fabrice nicol Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Thu, 17 Jun 2021 18:36:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 47408 X-GNU-PR-Package: emacs X-GNU-PR-Keywords: patch Original-Received: via spool by 47408-submit@debbugs.gnu.org id=B47408.162395494710043 (code B ref 47408); Thu, 17 Jun 2021 18:36:02 +0000 Original-Received: (at 47408) by debbugs.gnu.org; 17 Jun 2021 18:35:47 +0000 Original-Received: from localhost ([127.0.0.1]:55148 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ltwrj-0002bu-9z for submit@debbugs.gnu.org; Thu, 17 Jun 2021 14:35:47 -0400 Original-Received: from mail-wm1-f46.google.com ([209.85.128.46]:54135) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1ltwrf-0002bZ-NB for 47408@debbugs.gnu.org; Thu, 17 Jun 2021 14:35:46 -0400 Original-Received: by mail-wm1-f46.google.com with SMTP id j18so3884986wms.3 for <47408@debbugs.gnu.org>; Thu, 17 Jun 2021 11:35:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-language; bh=9jIDAKowMcvlI23xTg13VKwB8BkPDwUKyj/qrYm65yg=; b=NRtr3hVZkw1tHpdOsNaN6BDCj4NTdeXTOneerLiImAgnFUztqDiXcGuXHv9pYmwQ/X uYinQMVYm8xSKE9Vd7gOx90l0BT80i/k3AYCWeccab1wsNeIj2BcjXfpJluV4Tr80lK8 V5na4pkZUh7J4Cje8sN2m1jFKd+xnBxEBXnoi4Iq/8Paj9kB+21P7wFMDNjC3MnpWyQV w3/rkrU93Z4Bv+5JZHc778bkEHPD5Su6SnCKBydVBIH3RSzxS2rQ+5Q3pwn1c7f2aDXe B0rObTtDqTivVwKXIGVuJRFGqpiq2uNwvwoC1dgzo+k3bdp9+PbQxZaK71KkXHObq5Jf ilaA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language; bh=9jIDAKowMcvlI23xTg13VKwB8BkPDwUKyj/qrYm65yg=; b=k4/QleiADOoVOLTx8YUT/VsJdG93+mDNmfbS+ZawkjHoR9criQmwc2KhDoOTm+kGhU nHOcyx66Xu3vHSLxO2b8F8iImHu3Z9vYRlPQsFnjzyLJzXSAqgzdvhSeuuDhk8kwI149 wgCfLOAK9YIb7BxHeplpXkEIOc6CibswQiOTB0Oke1oqiT8jC/FWIJAH4cfhDf4t+oYJ TTIl106TAv568jr26nXStHaMVm5VlZIkb7e7DzzqfxnyjRIC3FXmrb6Rt6IJBwXUckIP 13QorKfNYX8t7UVzcIwEaaR8vG2sisHsGEFfYkCI7/W5yHAjTCm2LMXa9fitxDhpl95m dplA== X-Gm-Message-State: AOAM533WkhScksNdw7gQltuM05ypb51M+GNQ2gGe5IxR6bSNFntsYXBN 1NBcRFFKIc6s8PVGbVvpNPwKBmbBh9s= X-Google-Smtp-Source: ABdhPJxiiGJBjWM6mbOGALl3JBDEvkRjcDEk61O1TN7liPfrwZ9CNInmUjSV0/RadYtYirUU8glqoQ== X-Received: by 2002:a05:600c:20d:: with SMTP id 13mr6809013wmi.174.1623954937760; Thu, 17 Jun 2021 11:35:37 -0700 (PDT) Original-Received: from ?IPv6:2a01:cb1d:88b9:5c00:7b73:7901:965e:8523? ([2a01:cb1d:88b9:5c00:7b73:7901:965e:8523]) by smtp.gmail.com with ESMTPSA id h46sm7131419wrh.44.2021.06.17.11.35.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Thu, 17 Jun 2021 11:35:37 -0700 (PDT) In-Reply-To: <83wnqszphk.fsf@gnu.org> Content-Language: en-US X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:208672 Archived-At: This is a multi-part message in MIME format. --------------9455C4B7B967BD282768F775 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Hi, Eli, I could finalize my tests against the entire Mercury library code. All is OK. I applied your patch on top of mine. Also, I added two new corner-case fixes, which are mentioned in the commit message: 1. The first new fix is for 0-arity predicates and functions. Yes, Mercury has them. (They play the role of global immutable constants in other languages). They happened not to be caught by the previous code, now they are. 2. I also removed module names from within tag names. The point is that module name prefixing is optional in most cases, so if you leave the module prefix within the tag, you will fail to get to the declaration when striking M-. on a (non-prefixed) predicate name. It is better to remove the name altogether. This will automatically trigger an explicit tag. Fabrice >> This is intended. I commented this in the commit message (one-word declarations). > Understood, thanks. > >> To fix this second issue, I propose the change below, which should >> be applied on top of your patches: >> >> diff --git a/lib-src/etags.c b/lib-src/etags.c >> index 370e825..2b0288e 100644 >> --- a/lib-src/etags.c >> +++ b/lib-src/etags.c >> @@ -6585,10 +6585,8 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen) >> && c_isspace (s[pos - namelength - offset])) >> --offset; >> >> - /* There is no need to correct namelength or call notinname. */ >> - s[pos - offset - 1] = '\0'; >> - >> - make_tag (s + pos - namelength - offset, namelength, true, s, pos, lineno, linecharno); >> + make_tag (s + pos - namelength - offset, namelength - 1, true, >> + s, pos - offset - 1, lineno, linecharno); >> return pos; >> } >> >> I've verified that etags after this change still produces the correct >> TAGS file, including for the file univ.m you sent up-thread. >> >> Do you agree with the changes I propose? If not, could you please >> explain what I miss here? >> >> OK, this is another way of achieving an equivalent result. Please leave me until tomorrow to perform more >> tests so that I can formally confirm that this is fine. > Thanks. > > I also plan on adding a few lines from univ.m to accumulator.m, > because those few lines use a feature accumulator.m doesn't. Is this > OK with you? --------------9455C4B7B967BD282768F775 Content-Type: text/x-patch; charset=UTF-8; name="0001-Fix-Mercury-support-notably-quantified-procedures.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename*0="0001-Fix-Mercury-support-notably-quantified-procedures.patch" >From b4db1894e71b7aaa0be28b604a814f58bdabeef9 Mon Sep 17 00:00:00 2001 From: Fabrice Nicol Date: Thu, 17 Jun 2021 19:59:52 +0200 Subject: [PATCH] Fix Mercury support, notably quantified procedures. Correct the previous fix (did not correctly handle quantified types). Also fix the following issues: - remove module name (+ dot) from tags, as prefixing module name is often inconsistent in code and may cause tags to be too specific. - now tag 0-arity predicates and functions (':- func foo_14.') - now tag one-word declarations (':- interface.') * lib-src/etags.c (mercury_pr): Pass the correct NAME and NAMELEN arguments to 'make_tag'. --- lib-src/etags.c | 126 +++++++++++++++++++++++++++++++----------------- 1 file changed, 83 insertions(+), 43 deletions(-) diff --git a/lib-src/etags.c b/lib-src/etags.c index 9f20e44caf..bd57ede2f3 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c @@ -6081,10 +6081,10 @@ prolog_atom (char *s, size_t pos) pos++; if (s[pos] != '\'') break; - pos++; /* A double quote */ + pos++; /* A double quote */ } else if (s[pos] == '\0') - /* Multiline quoted atoms are ignored. */ + /* Multiline quoted atoms are ignored. */ return 0; else if (s[pos] == '\\') { @@ -6119,6 +6119,13 @@ prolog_atom (char *s, size_t pos) static bool is_mercury_type = false; static bool is_mercury_quantifier = false; static bool is_mercury_declaration = false; +typedef struct +{ + size_t pos; /* Position reached in parsing tag name. */ + size_t namelength; /* Length of tag name */ + size_t totlength; /* Total length of parsed tag: this field is currently + reserved for control and debugging. */ +} mercury_pos_t; /* * Objective-C and Mercury have identical file extension .m. @@ -6374,10 +6381,12 @@ mercury_skip_comment (linebuffer *plb, FILE *inf) "initialise", "finalise", "mutable", "module", "interface", "implementation", "import_module", "use_module", "include_module", "end_module", "some", "all"}; -static size_t +static mercury_pos_t mercury_decl (char *s, size_t pos) { - if (s == NULL) return 0; + mercury_pos_t null_pos = {0, 0, 0}; + + if (s == NULL) return null_pos; size_t origpos; origpos = pos; @@ -6398,7 +6407,8 @@ mercury_decl (char *s, size_t pos) if (is_mercury_quantifier) { if (strcmp (buf, "pred") != 0 && strcmp (buf, "func") != 0) /* Bad syntax. */ - return 0; + return null_pos; + is_mercury_quantifier = false; /* Reset to base value. */ found_decl_tag = true; } @@ -6418,7 +6428,7 @@ mercury_decl (char *s, size_t pos) is_mercury_quantifier = true; } - break; /* Found declaration tag of rank j. */ + break; /* Found declaration tag of rank j. */ } else /* 'solver type' has a blank in the middle, @@ -6461,24 +6471,36 @@ mercury_decl (char *s, size_t pos) if (found_decl_tag) pos = skip_spaces (s + pos) - s; /* Skip len blanks again. */ else - return 0; + return null_pos; } /* From now on it is the same as for Prolog except for module dots. */ + size_t start_of_name = pos; + if (c_islower (s[pos]) || s[pos] == '_' ) { /* The name is unquoted. Do not confuse module dots with end-of-declaration dots. */ + int module_dot_pos = 0; while (c_isalnum (s[pos]) || s[pos] == '_' || (s[pos] == '.' /* A module dot. */ && s + pos + 1 != NULL - && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_'))) + && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_') + && (module_dot_pos = pos))) /* Record module dot position. + Erase module from name. */ ++pos; - return pos - origpos; + if (module_dot_pos) + { + start_of_name = module_dot_pos + 2; + ++pos; + } + + mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos}; + return position; } else if (s[pos] == '\'') { @@ -6493,28 +6515,37 @@ mercury_decl (char *s, size_t pos) ++pos; /* A double quote. */ } else if (s[pos] == '\0') /* Multiline quoted atoms are ignored. */ - return 0; + return null_pos; else if (s[pos] == '\\') { if (s[pos+1] == '\0') - return 0; + return null_pos; pos += 2; } else ++pos; } - return pos - origpos; + + mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos}; + return position; } else if (is_mercury_quantifier && s[pos] == '[') /* :- some [T] pred/func. */ { for (++pos; s + pos != NULL && s[pos] != ']'; ++pos) {} - if (s + pos == NULL) return 0; + if (s + pos == NULL) return null_pos; ++pos; pos = skip_spaces (s + pos) - s; - return mercury_decl (s, pos) + pos - origpos; + mercury_pos_t position = mercury_decl (s, pos); + position.totlength += pos - origpos; + return position; + } + else if (s[pos] == '.') /* as in ':- interface.' */ + { + mercury_pos_t position = {pos, pos - origpos + 1, pos - origpos}; + return position; } else - return 0; + return null_pos; } static ptrdiff_t @@ -6523,6 +6554,7 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen) size_t len0 = 0; is_mercury_type = false; is_mercury_quantifier = false; + bool stop_at_rule = false; if (is_mercury_declaration) { @@ -6530,38 +6562,46 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen) len0 = skip_spaces (s + 2) - s; } - size_t len = mercury_decl (s, len0); - if (len == 0) return 0; - len += len0; - - if (( (s[len] == '.' /* This is a statement dot, not a module dot. */ - || (s[len] == '(' && (len += 1)) - || (s[len] == ':' /* Stopping in case of a rule. */ - && s[len + 1] == '-' - && (len += 2))) - && (lastlen != len || memcmp (s, last, len) != 0) + mercury_pos_t position = mercury_decl (s, len0); + size_t pos = position.pos; + int offset = 0; /* may be < 0 */ + if (pos == 0) return 0; + + /* Skip white space for: + a. rules in definitions before :- + b. 0-arity predicates with inlined modes. + c. possibly multiline type definitions */ + + while (c_isspace (s[pos])) { ++pos; ++offset; } + + if (( ((s[pos] == '.' && (pos += 1)) /* case 1 + This is a statement dot, + not a module dot. */ + || c_isalnum(s[pos]) /* 0-arity procedures */ + || (s[pos] == '(' && (pos += 1)) /* case 2: arity > 0 */ + || ((s[pos] == ':') /* case 3: rules */ + && s[pos + 1] == '-' && (stop_at_rule = true))) + && (lastlen != pos || memcmp (s, last, pos) != 0) ) /* Types are often declared on several lines so keeping just the first line. */ - || is_mercury_type) + + || is_mercury_type) /* When types are implemented. */ { - char *name = skip_non_spaces (s + len0); - size_t namelen; - if (name >= s + len) - { - name = s; - namelen = len; - } - else - { - name = skip_spaces (name); - namelen = len - (name - s); - } - /* Remove trailing non-name characters. */ - while (namelen > 0 && notinname (name[namelen - 1])) - namelen--; - make_tag (name, namelen, true, s, len, lineno, linecharno); - return len; + size_t namelength = position.namelength; + if (stop_at_rule && offset) --offset; + + /* Left-trim type definitions. */ + + while (pos > namelength + offset + && c_isspace (s[pos - namelength - offset])) + --offset; + + /* There is no need to correct namelength or call notinname. */ + + make_tag (s + pos - namelength - offset, namelength - 1, true, + s, pos - offset - 1, lineno, linecharno); + return pos; } return 0; -- 2.32.0 --------------9455C4B7B967BD282768F775--