Sujet : Re: Command line globber/tokenizer library for C?
De : tr.17687 (at) *nospam* z991.linuxsc.com (Tim Rentsch)
Groupes : comp.lang.cDate : 18. Sep 2024, 14:01:33
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <86wmj986aa.fsf@linuxsc.com>
References : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
User-Agent : Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Michael S <
already5chosen@yahoo.com> 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).