From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on inbox.vuxu.org X-Spam-Level: X-Spam-Status: No, score=-3.4 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED autolearn=ham autolearn_force=no version=3.4.4 Received: (qmail 891 invoked from network); 16 Dec 2022 16:43:10 -0000 Received: from zero.zsh.org (2a02:898:31:0:48:4558:7a:7368) by inbox.vuxu.org with ESMTPUTF8; 16 Dec 2022 16:43:10 -0000 ARC-Seal: i=1; cv=none; a=rsa-sha256; d=zsh.org; s=rsa-20210803; t=1671208990; b=B+mq6CAMavzJkRKsHvrOPO1k+dGlWRDsAlvHW7iv00qYxXjJy4+oRlqqeFRF50QZfi0R6WzytR drK5BI1rMpX2E1GcJEHFqUTllhEepi5hQdDxG/SVHTTL6TPdK6P2pKpNTnBD9T9tKm3sMyqZkv nzDrOac4+MQv1oEKg8uZHZmLf6IXLD+xL8zScWekvceRQB46esfl3v1lzufoixmKwfHE1SHpXM ZF7TBa+5ytvL6vN6TV7Vz/zRH3pstdvdUW23UvdEwUVwt4mg1+olw/ei5WLoG2FLfVOBs2PwmC cfFHWe6IsJJubAgARPRgSxRfVvjuJw9Jpq98kfRwk7pbKQ==; ARC-Authentication-Results: i=1; zsh.org; iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97; dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256; dmarc=pass header.from=ntlworld.com; arc=none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed; d=zsh.org; s=rsa-20210803; t=1671208990; bh=vUKXle6R56pUY9ryS7wx0KyKkRKmZRe0DjJRIsVvJ9o=; h=List-Archive:List-Owner:List-Post:List-Unsubscribe:List-Subscribe:List-Help: List-Id:Sender:Content-Transfer-Encoding:Content-Type:MIME-Version:Subject: Message-ID:To:From:Date:DKIM-Signature:DKIM-Signature; b=NSka+SlS9t1IowHTiCMOL/PpaRcPy9kNyDIi2AyXKvdu7LyaM4OqNuxHYdNrSj/dSg6U0U7EtB 9bJG04bPVPCmurWJXkCx/RjLFk6y+mgiyMeGajG00aZf5aBU9iXxnV1LWnygX8oIlA21vM0jRR s/1REIKmg2l+7PNcFW3QpIgNdtQTk0GaCFy8zi3nBFuYS1IUaxMjH8EhFlMxjB91yHeoDTPKAg 040FbTj3zNZxxdqatAkujLv4KB6BHxtCEC0eFyXmY5P8VM66lzhCsJT1Uxx3MDSpirp2DRAbLv smV6MoJetuNgaNEcDVsTk+aquwnG65+GJ4fHzoEZfTsBFQ==; DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=zsh.org; s=rsa-20210803; h=List-Archive:List-Owner:List-Post:List-Unsubscribe: List-Subscribe:List-Help:List-Id:Sender:Content-Transfer-Encoding: Content-Type:MIME-Version:Subject:Message-ID:To:From:Date:Reply-To:Cc: Content-ID:Content-Description:Resent-Date:Resent-From:Resent-Sender: Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References; bh=ynczTfIFGVtV+fzsobIC3n1qnZKIAOYhEij3H1yI6AI=; b=WhLNw8OqNw//CR3+jNim8MO5/X +gNtXNS+FKA0RXu1IxIUkRLfQ2mT3HgiyPRSZcF05QcBzDIfqjoU2nOSt1np+HN3qVUQM0QJ38Nx2 aGnkAz/uXCxen0oBXJLBVb4YJKwa70XEvNcTOSKncHkC33G2XSYP0GAusysSya0pnMOu9pWI3u6aF 1qTuhcpSrzMor4yPIsK55Y1BhSBPRnhOq0ViDDFT18ncUTbff/PFFsJIU3EeVOB9OZRHlvxStBI2i gGqD4I5f+cJcMIBM5Cai2a7Dbc1t5ArUWPB8kj4pAfz5Ik/wSKexOTqMgcsuVPj6vDL2cYtCAzLGB Wegdhw4A==; Received: by zero.zsh.org with local id 1p6Dnh-000DCw-Sj; Fri, 16 Dec 2022 16:43:09 +0000 Authentication-Results: zsh.org; iprev=pass (smtpq2.tb.ukmail.iss.as9143.net) smtp.remote-ip=212.54.57.97; dkim=pass header.d=ntlworld.com header.s=meg.feb2017 header.a=rsa-sha256; dmarc=pass header.from=ntlworld.com; arc=none Received: from smtpq2.tb.ukmail.iss.as9143.net ([212.54.57.97]:37208) by zero.zsh.org with esmtps (TLS1.2:ECDHE-RSA-AES256-GCM-SHA384:256) id 1p6DnR-000CtT-O2; Fri, 16 Dec 2022 16:42:54 +0000 Received: from [212.54.57.82] (helo=smtp3.tb.ukmail.iss.as9143.net) by smtpq2.tb.ukmail.iss.as9143.net with esmtp (Exim 4.90_1) (envelope-from ) id 1p6DnR-0006hH-Ab for zsh-workers@zsh.org; Fri, 16 Dec 2022 17:42:53 +0100 Received: from oxbe14.tb.ukmail.iss.as9143.net ([172.25.160.145]) by smtp3.tb.ukmail.iss.as9143.net with ESMTP id 6DnRpnxosYBhJ6DnRpqmIk; Fri, 16 Dec 2022 17:42:53 +0100 X-Env-Mailfrom: p.w.stephenson@ntlworld.com X-Env-Rcptto: zsh-workers@zsh.org X-SourceIP: 172.25.160.145 X-CNFS-Analysis: v=2.4 cv=Vd8xfnl9 c=1 sm=1 tr=0 ts=639ca00d cx=a_exe a=DLFSjXpdtQHJ5hZ/0KPoEg==:117 a=8QvskaeBrsgA:10 a=IkcTkHD0fZMA:10 a=VEAUHPWEz7YA:10 a=Go2N6k3lZ3be5UJShb0A:9 a=QEXdDO2ut3YA:10 X-Authenticated-Sender: p.w.stephenson@ntlworld.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ntlworld.com; s=meg.feb2017; t=1671208973; bh=vUKXle6R56pUY9ryS7wx0KyKkRKmZRe0DjJRIsVvJ9o=; h=Date:From:To:Subject; b=1BvboTgPDNV/6zH2AOda/f+kZnexX8rjQ53tCctymUAJ39xVo/Rs3mqgHGWUNFsol LM7i57Pu9cuGTO3JnBYp2FImneAlFnHU5dNkbLhAMGngzCCN7u73KGsN7ZwiIvNtpO b6Zaol+z28mzCPlt5Tz713jbuBF4ISsyJd1cSWNmNKyRVr2YBXskfk4X6wHnqxm/Fa RA0knD+AEGfzOisPTaK64TrjhYhsV2A6VTw2iI9tQWUX7bzpRpxrVz1U6AGQaq8bWM IkyMaX4cbEt33rAJcnkAnmkfUWQT3a8KIkRTRidjzP7mCYNxTLZIPCPXw6wEUoW3Gk I9jkXSJrYR2YQ== Date: Fri, 16 Dec 2022 16:42:53 +0000 (GMT) From: Peter Stephenson To: zsh workers Message-ID: <527664940.183302.1671208973242@mail.virginmedia.com> Subject: zsh_error_db --- hash-based database of error messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Priority: 3 Importance: Normal X-Mailer: Open-Xchange Mailer X-Originating-IP: 147.161.225.104 X-Originating-Client: open-xchange-appsuite X-CMAE-Envelope: MS4xfB7bX8eFesjaPWJyqZGGffUOcHzyqwl3jGVdXx0I4YeuWh3mV+CypfCbKPBP/a8uL0WuTUL9JgfIPi55OEqkId1BeviTXRA03vKy27zXRHGmAr1r0KUH rP1XjWi0XrDOEu9RGEu9N4bXLHqDXy2QnA070XHZH/mOrlneAHzXw5HdjtnaJN0BuA5X+IKzOo4Tx4i6NL4HCVjcsgBaLqP3xrUzsR6se4mVDEdUkaGISWWU X-Seq: 51224 Archived-At: X-Loop: zsh-workers@zsh.org Errors-To: zsh-workers-owner@zsh.org Precedence: list Precedence: bulk Sender: zsh-workers-request@zsh.org X-no-archive: yes List-Id: List-Help: , List-Subscribe: , List-Unsubscribe: , List-Post: List-Owner: List-Archive: Following on from the retread of the discussion on error messages, here's a very simply proof of concept for a hash-based database of error messages. Even if it's adopted I don't intend the C code to get much larger as the point is to allow it to be able to do everything in shell code. Apart from more user-friendly messages which someone with no access to the C code can dedicate their life to tweaking, this is obviously a boon for internationalization (which I approve of so much I've even spelled it with a 'z'). Trivial example: % typeset -A zsh_error_db=(E3 "not very many matches found: %s") % setopt nomatch % echo fudge* zsh: not very many matches found: fudge* Apart from updating the error message to examine the hash, the only change is to prefix the error message format string with the code such as "E3" and a colon. This would obviously be done universally. The E, a set of digits, and a colon is tested for. I originally didn't have the E in front, but see my other comment on hash lookups below. There is obviously room for doing this differently, and some way of making it easy to avoid duplicates would probably be good, but I think it needs to be reasonably simple. I didn't look exhaustively, but it seems we don't have a potted function that takes the name of a hash and an entry and looks it up as a string, though the code for this isn't very verbose anyway. We don't actually force the entry of the hash to be a string type, but in practice I think it always is. The "E" prefix results because at one stage numbers were doing positional parameter lookups; I've since then gone into the hash handling at lower level so that doesn't happen any more, but I left the E as giving a slightly more extensible interface, which I expect everyone else is going to tear apart anyway. The signatures of the format strings, i.e. where the % escapes live, is checked for, though if there are cases where we have more than a single letter code it'll fall over. There's no provision for reordering escapes, either, but I wouldn't expect to do that in an initial implementation anyway. pws diff --git a/Src/exec.c b/Src/exec.c index 2b7e0c7c5..5ad56eced 100644 --- a/Src/exec.c +++ b/Src/exec.c @@ -3333,7 +3333,7 @@ execcmd_exec(Estate state, Execcmd_params eparams, * has provided a status. */ if (badcshglob == 1) { - zerr("no match"); + zerr("E2:no match"); lastval = 1; if (forked) _realexit(); diff --git a/Src/glob.c b/Src/glob.c index 490bafc37..493c4227a 100644 --- a/Src/glob.c +++ b/Src/glob.c @@ -1868,7 +1868,7 @@ zglob(LinkList list, LinkNode np, int nountok) if (isset(CSHNULLGLOB)) { badcshglob |= 1; /* at least one cmd. line expansion failed */ } else if (isset(NOMATCH)) { - zerr("no matches found: %s", ostr); + zerr("E3:no matches found: %s", ostr); zfree(matchbuf, 0); restore_globstate(saved); return; diff --git a/Src/subst.c b/Src/subst.c index 0f98e6ea3..571673d11 100644 --- a/Src/subst.c +++ b/Src/subst.c @@ -504,7 +504,7 @@ globlist(LinkList list, int flags) if (noerrs) badcshglob = 0; else if (badcshglob == 1) - zerr("no match"); + zerr("E1:no match"); } /* perform substitution on a single word */ diff --git a/Src/utils.c b/Src/utils.c index edf5d3df7..e8070df1e 100644 --- a/Src/utils.c +++ b/Src/utils.c @@ -119,6 +119,93 @@ set_widearray(char *mb_array, Widechar_array wca) } #endif +/**/ +static const char * +zerrmsg_bad_signature(const char *code, const char *internal) +{ + /* Don't attempt to use error message system here! */ + fprintf(stderr, "zsh_err_db entry `%s' has incorrect signature for:\n%s\n", + code, internal); + return internal; +} + +/* Attempt to use hash zsh_error_db to update message */ +/**/ +static const char * +zerrmsg_from_hash(const char *msg) +{ + Param errdb, msgpm; + HashTable errtab; + const char *postcode = msg, *sigmsg, *sigvar, *imsg; + char *errcode, *newmsg; + + if (*postcode++ != 'E') + return msg; + while (idigit(*postcode)) + ++postcode; + if (postcode == msg || *postcode != ':') + return msg; + + imsg = postcode+1; + errdb = (Param)paramtab->getnode(paramtab, "zsh_error_db"); + if (!errdb || !(errdb->node.flags & PM_HASHED)) { + return imsg; + } + + errcode = dupstrpfx(msg, postcode-msg); + errtab = errdb->gsu.h->getfn(errdb); + if (!errtab) + return imsg; + msgpm = (Param)errtab->getnode(errtab, errcode); + if (PM_TYPE(msgpm->node.flags)) { + /* Not a plain string, bail out (safety) */ + return imsg; + } + newmsg = msgpm->gsu.s->getfn(msgpm); + + if (!newmsg || !*newmsg) + return imsg; + + /* Check the %-signature matches */ + sigmsg = imsg; + sigvar = newmsg; + + for (;;) { + while (*sigmsg && *sigmsg != '%') + sigmsg++; + if (!*sigmsg) + break; + ++sigmsg; + if (*sigmsg == '%') { + ++sigmsg; + continue; + } + while (*sigvar) { + if (*sigvar++ == '%') + { + if (*sigvar != '%') + break; + ++sigvar; + } + } + if (!*sigvar || *sigvar != *sigmsg) + return zerrmsg_bad_signature(errcode, imsg); + ++sigvar; + ++sigmsg; + } + while (*sigvar) + { + if (*sigvar++ == '%') + { + if (*sigvar != '%') + return zerrmsg_bad_signature(errcode, imsg); + ++sigvar; + } + } + + return newmsg; +} + /* Print an error @@ -305,6 +392,8 @@ zerrmsg(FILE *file, const char *fmt, va_list ap) } else fputc((unsigned char)' ', file); + fmt = zerrmsg_from_hash(fmt); + while (*fmt) if (*fmt == '%') { fmt++;