From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Pierre Lindenbaum Newsgroups: gmane.lisp.guile.user Subject: Re: using guile like a awk filter in a C program. Date: Fri, 24 May 2024 09:31:21 +0200 Message-ID: References: <60c7c61c6dea289c9a1d8e59829f9c91@univ-nantes.fr> <87v83ce2en.fsf@gmail.com> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="31514"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Thunderbird/102.11.0 To: guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Fri May 24 09:20:34 2024 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 1sAPEA-00080K-4x for guile-user@m.gmane-mx.org; Fri, 24 May 2024 09:20:34 +0200 Original-Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1sAPDb-0008D8-5Z; Fri, 24 May 2024 03:19:59 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sAPDY-0008A6-Ej for guile-user@gnu.org; Fri, 24 May 2024 03:19:56 -0400 Original-Received: from smtptls2-lmb.cpub.univ-nantes.fr ([2001:660:7220:385:193:52:103:111] helo=smtp-tls.univ-nantes.fr) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1sAPDV-0006id-EP for guile-user@gnu.org; Fri, 24 May 2024 03:19:56 -0400 Original-Received: from localhost (localhost [127.0.0.1]) by smtp-tls.univ-nantes.fr (Postfix) with ESMTP id 4D3578B5 for ; Fri, 24 May 2024 09:19:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=univ-nantes.fr; s=mailv2; t=1716535186; bh=WOmGM0yODHNl+th+jj/OIud1P9m6BqJBpWUmwQykCTU=; h=Date:Subject:From:To:References:In-Reply-To:From; b=Q9kt8Int9ftJ/bcgcUC1qOkAUDSExPyJC4NxOwFcBlM+tX2z3FTaGkM/3lxqDVgRC uiiRB/PqudnjPfCVNmNecfcWYh91hUjsFKpGl3I742sw8WoBZLQAA3S5Byqj0E6r1p HDoOCaWiTlgveTWqm9nBfWCcNRNcrWMCre9nDWRfErOX0wG4R9ZAVogSHPq2fwVhlf lrbO5sKEIo/DDm37E8pbKlCXJ66rlRw3oGqFFXzey9++IxpgQCc/cGl8E6uZAj+8bp WxzIsrnrN5TpZQZOgULox8zP/HvciCdkfwaYbZKv8sTw9yRQyaa4rC2y2e0GNCTth5 u/wdYZ+29jfoQ== X-Virus-Scanned: Debian amavisd-new at smtptls1-lmb.cpub.univ-nantes.fr Original-Received: from smtp-tls.univ-nantes.fr ([127.0.0.1]) by localhost (smtptls2-lmb.cpub.univ-nantes.fr [127.0.0.1]) (amavisd-new, port 10024) with LMTP id jR5tIvtSgzyY for ; Fri, 24 May 2024 09:19:46 +0200 (CEST) Original-Received: from [172.18.240.128] (unknown [172.18.240.128]) (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-tls.univ-nantes.fr (Postfix) with ESMTPSA id 2CA5F30B for ; Fri, 24 May 2024 09:19:46 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=univ-nantes.fr; s=mailv2; t=1716535186; bh=WOmGM0yODHNl+th+jj/OIud1P9m6BqJBpWUmwQykCTU=; h=Date:Subject:From:To:References:In-Reply-To:From; b=Q9kt8Int9ftJ/bcgcUC1qOkAUDSExPyJC4NxOwFcBlM+tX2z3FTaGkM/3lxqDVgRC uiiRB/PqudnjPfCVNmNecfcWYh91hUjsFKpGl3I742sw8WoBZLQAA3S5Byqj0E6r1p HDoOCaWiTlgveTWqm9nBfWCcNRNcrWMCre9nDWRfErOX0wG4R9ZAVogSHPq2fwVhlf lrbO5sKEIo/DDm37E8pbKlCXJ66rlRw3oGqFFXzey9++IxpgQCc/cGl8E6uZAj+8bp WxzIsrnrN5TpZQZOgULox8zP/HvciCdkfwaYbZKv8sTw9yRQyaa4rC2y2e0GNCTth5 u/wdYZ+29jfoQ== Content-Language: en-US In-Reply-To: Received-SPF: pass client-ip=2001:660:7220:385:193:52:103:111; envelope-from=lindenbaum-p@univ-nantes.fr; helo=smtp-tls.univ-nantes.fr X-Spam_score_int: -55 X-Spam_score: -5.6 X-Spam_bar: ----- X-Spam_report: (-5.6 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, NICE_REPLY_A=-1.153, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.29 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-bounces+guile-user=m.gmane-mx.org@gnu.org Xref: news.gmane.io gmane.lisp.guile.user:19689 Archived-At: > I want to call scheme from C. > > The C loop scans the binary data and a scheme script would be used to accept/reject a record. Something like > > >         ./my-c-program --filter '(and (is-male?) (is-german?) )' persons.data > male_from_germany.data > > >>> - furthermore, what's the best practice to include the user's script in >>> a larger script that would include the definitions of `variant-is-snp?` >>> , `variant-allele-count`, etc... >> Maybe modules? Ok , this it what I got so far. I tested my idea with a C program scanning a stream of integers on stdin . I put  the C code and the Makefile below (or you can read it at https://gist.github.com/lindenb/7b7793ced81fc3a4a566333f5149d65a ) : The invocation looks like: seq 1 100 | ./a.out '(= (modulo (_get) 7) 0)' 7 14 21 28 35 42 49 56 63 70 77 84 91 98 where (_get) returns the current integer. Is it the correct way to initialize the script ? it looks ugly. Currently the user just define the 'filter' part and then I include this string in a larger code. Ant how should I design this if I want to include modules, custom functions,...  ? Furthermore, I'd like to include a module that would be embedded in the C code , in a big const string to avoid any external file, it it possible ? Thank you for your suggestions Pierre /***************** C code ************************************************/ #include #include struct Global {     /** inputstream */     FILE* in;     /** currrent value */     int value;     /** contains script as string */     char buffer[2048];     }; static struct Global global; /** retrieve the next record, return #t on success */ static SCM _next () {   int ret = fscanf(global.in,"%d", &(global.value));   if(ret!=1) return SCM_BOOL_F;   return SCM_BOOL_T; } /** get current number */ static SCM _get () {   return scm_from_int(global.value); } /** output current number */ static SCM _emit () {   fprintf(stderr,"%d\n",global.value);   return SCM_BOOL_T; } /** dispose memory associated */ static SCM _dispose () {   return SCM_BOOL_T; } static void* inner_main (void *data) {     struct Global* g= (struct Global*)data;     scm_c_define_gsubr("_next", 0, 0, 0, _next);     scm_c_define_gsubr("_get", 0, 0, 0, _get);     scm_c_define_gsubr("_emit", 0, 0, 0, _emit);     scm_c_define_gsubr("_dispose", 0, 0, 0, _dispose);     scm_c_eval_string(g->buffer);     return 0; } int main(int argc,char** argv) {     if(argc!=2) return -1;     global.value=1;     global.in = stdin;     sprintf(global.buffer,"(while (_next) (if %s  (_emit)   ) (_dispose) )  ",argv[1]);     scm_with_guile(inner_main,(void*)&global);     return 0;     } /***************** Makefile ************************************************/GUILE_VERSION=2.2 # Tell the C compiler where to find CFLAGS=`pkg-config --cflags guile-$(GUILE_VERSION)` # Tell the linker what libraries to use and where to find them. LIBS=`pkg-config --libs guile-$(GUILE_VERSION)` test: a.out     seq 1 100 | ./a.out '(= (modulo (_get) 7) 0)' a.out: filter.c     $(CC) $(CFLAGS) -o $@ $< $(LIBS)