From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Leo Prikler Newsgroups: gmane.lisp.guile.user Subject: Re: Lost input when using suspendable read-line Date: Mon, 23 Aug 2021 23:45:19 +0200 Message-ID: <04425a0337fa3d75f367d7e390c280ff5aa1bb1c.camel@student.tugraz.at> References: <87mtp8vmap.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="24128"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Evolution 3.34.2 To: Maxim Cournoyer , guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Tue Aug 24 14:54:08 2021 Return-path: Envelope-to: guile-user@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 1mIVwO-0005yh-Ak for guile-user@m.gmane-mx.org; Tue, 24 Aug 2021 14:54:08 +0200 Original-Received: from localhost ([::1]:59754 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1mIVwN-0007Du-64 for guile-user@m.gmane-mx.org; Tue, 24 Aug 2021 08:54:07 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:33506) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mIHlV-0003A7-9p for guile-user@gnu.org; Mon, 23 Aug 2021 17:45:57 -0400 Original-Received: from mailrelay.tugraz.at ([129.27.2.202]:37487) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1mIHlS-0003wu-4I for guile-user@gnu.org; Mon, 23 Aug 2021 17:45:56 -0400 Original-Received: from [10.0.0.4] (62-47-226-13.adsl.highway.telekom.at [62.47.226.13]) by mailrelay.tugraz.at (Postfix) with ESMTPSA id 4Gtm554KHtz1DPxw; Mon, 23 Aug 2021 23:45:45 +0200 (CEST) DKIM-Filter: OpenDKIM Filter v2.11.0 mailrelay.tugraz.at 4Gtm554KHtz1DPxw DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=tugraz.at; s=mailrelay; t=1629755145; bh=sphMTp515sK1G7MZN2rPJ5Q6gBszH7354KmE9yXqR8Q=; h=Subject:From:To:Date:In-Reply-To:References:From; b=CCrMoxhriZ2gc5svYZCI95nzxxaxw2DlzPvU6ApCifAGDoPAFPfIwHusrsXgbG4C2 FshqxgTDQmM4YJ9IKis8wswW3MdmiM/yrxQK2hwIJFfWohHfkE+6NxcxnruGoeDWPg 6vM13bamMP4RNtDDL1doed4FU8qLF3KUEmtWEvDI= In-Reply-To: <87mtp8vmap.fsf@gmail.com> X-TUG-Backscatter-control: bt4lQm5Tva3SBgCuw0EnZw X-Scanned-By: MIMEDefang 2.74 on 129.27.10.117 Received-SPF: pass client-ip=129.27.2.202; envelope-from=leo.prikler@student.tugraz.at; helo=mailrelay.tugraz.at X-Spam_score_int: -42 X-Spam_score: -4.3 X-Spam_bar: ---- X-Spam_report: (-4.3 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Tue, 24 Aug 2021 08:53:49 -0400 X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.io gmane.lisp.guile.user:17692 Archived-At: Hi, Am Montag, den 23.08.2021, 00:04 -0400 schrieb Maxim Cournoyer: > --8<---------------cut here---------------start------------->8--- > (use-modules (ice-9 match) > (ice-9 rdelim) > (ice-9 suspendable-ports)) > > (install-suspendable-ports!) > > (define (read-line* port cont) > ;; Return, as a pair, the line and the terminated delimiter > or end-of-file > ;; object. When a line cannot be read, return the > '(suspended > ;; . partial-continuation) pair, where partial-continuation > can be > ;; evaluated in the future when the port is ready to be read. > (call-with-prompt 'continue > (lambda () > (parameterize ((current-read-waiter > (lambda (_) > (abort-to-prompt 'continue)))) > (if cont > (cont) > (read-line port 'split)))) > (lambda (partial-continuation) > (cons 'suspended partial-continuation)))) > > (define (main) > [...] > (let loop ((cont #f)) > (match (select (list (port->fdes port)) '() '()) > (((fdes ..1) () ()) > (let next-line ((line+delim (read-line* port cont))) > (match line+delim > (('suspended . partial-continuation) > (loop partial-continuation)) > ((line . _) > (format #t "~a~%" line) > (next-line (read-line* port cont))))))))))) > > (main) > --8<---------------cut here---------------end--------------->8--- This main loop appears broken. Look at the value of cont over time. On the first few lines, before suspending, you will read all the lines just fine. But afterwards it will be set to partial-continuation, even if said continuation is no longer current. This appears to be no issue if you need less than one continuation to finish the line, but if you need two or more, the outer continuation will cause you to redo the inner over and over again. I tried to make this loop somewhat more sensible: --8<---------------cut here---------------start------------->8--- (define port (car child->parent-pipe)) (define cont (make-parameter #f)) (define do-read (lambda () (match (select (list (port->fdes port)) '() '()) (((fdes ..1) () ()) (match (read-line* port (cont)) (('suspended . partial-cont) partial-cont) ((line . _) (format #t "~a~%" line) #f)))))) (let loop ((cont? (do-read))) (loop (parameterize ((cont cont?)) (do-read))))))) --8<---------------cut here---------------end--------------->8--- Here, each continuation is used exactly once, and that is to finish the current line. With this, I typically get output of the style: --8<---------------cut here---------------start------------->8--- Line 1 [wait for it...] Line 2 Line 3 Done! Line 1 [wait for it...] --8<---------- -----cut here---------------end--------------->8--- So it's not perfect either, but it's somewhat better than what you have currently. I'd hazard a guess that there are simpler implementations that need not make use of parameters, particularly because I kinda eliminated the inner loop anyway. A simpler fix, which retains your structure is to use (next-line (read-line* port #f))))))))))) in the case where a line has already been read. This also seems to have the desired behaviour of waiting after the "Done!" line. Regards, Leo