Path: csiph.com!news.swapon.de!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: Command line globber/tokenizer library for C? Date: Wed, 18 Sep 2024 06:01:33 -0700 Organization: A noiseless patient Spider Lines: 64 Message-ID: <86wmj986aa.fsf@linuxsc.com> References: <20240912181625.00006e68@yahoo.com> <20240912223828.00005c10@yahoo.com> <861q1nfsjz.fsf@linuxsc.com> <20240915122211.000058b1@yahoo.com> <20240918024611.000002f3@yahoo.com> <20240918114305.00002317@yahoo.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Wed, 18 Sep 2024 15:01:36 +0200 (CEST) Injection-Info: dont-email.me; posting-host="90f5f055cba32b807bf2e550ae581e94"; logging-data="87180"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/XKbKBhywm/nG+Ug1zn9wy0oA18g2Qzlo=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:F0qhvnbOrlfZzK4dt3RZA51cTfQ= sha1:0H/9wUDFIEwPcPKIuFPp4x/8ktI= Xref: csiph.com comp.lang.c:388451 Michael S writes: [...] > Since I am not accustomed to the functional programming style, for > me even a boring variant [not shown] is way too entertaining. I > prefer mundane (untested, could be buggy): > > static > const char* collect_word(const char *s) { > _Bool w = 0; > char c; > while ((c = *s) != 0) { > if (!w && is_space(c)) > break; > if (c == '"') > w = !w; > ++s; > } > return s; > } > > void words_do(const char *s, Gopher go ){ > char c; > while ((c = *s) != 0) { > if (is_space(c)) { > ++s; > } else { > const char *r = s; > s = collect_word(s); > go->f(go, r, s); > } > } > } If writing in an imperative-rather-than-functional style, I would likely gravitate toward something like this: static const char *process_word( const char *, Gopher ); void words_do( const char *s, Gopher go ){ char c; while( c = *s++ ){ if( ! is_space(c) ) s = process_word( s-1, go ); } } const char * process_word( const char *r, Gopher go ){ const char *s = r; _Bool q = 0; do q ^= *s++ == '"'; while( *s && (q || !is_space(*s)) ); return go->f( go, r, s ), s; } which seems to result in slightly better generated code than my functional version, in a few spot checks using gcc or clang under various -O settings (-Os, -O2, -O3).