tcsh-org / tcsh

This is a read-only mirror of the tcsh code repository.
https://www.tcsh.org/
Other
229 stars 42 forks source link

$?< for substituting whether there is available data from stdin. #90

Closed Krush206 closed 3 months ago

Krush206 commented 7 months ago

Substitutes 1 if there is available data from stdin, 0 if there is not.

zoulasc commented 3 months ago

Well, you can't assume you have poll(2) available (needs autoconf tests)... Perhaps a simpler way is:

--- a/sh.dol.c
+++ b/sh.dol.c
@@ -450,8 +450,18 @@ Dgetdol(void)
     case '<'|QUOTE: {
        static struct Strbuf wbuf; /* = Strbuf_INIT; */

-       if (bitset)
+       if (bitset) {
+#ifdef FIONREAD
+           int chrs;
+           if (ioctl(OLDSTD, FIONREAD, (ioctl_t) & chrs) == -1)
+               chrs = 0;
+           setDolp(putn((tcsh_number_t)chrs));
+           cleanup_until(name);
+           goto eatbrac;
+#else
            stderror(ERR_NOTALLOWED, "$?<");
+#endif
+       }
        if (dimen)
            stderror(ERR_NOTALLOWED, "$#<");
        if (length)

But that will always return 0 since they are no queued chars. The poll version will always return 0 too... How do you propose using it?

Krush206 commented 3 months ago

Thanks for the input. Your alternative works fine. However, as with poll(2), I'm concerned with regards to portability. If the system lacks FIONREAD, the script will fail. If a warning could be, somehow, shown, it would be less of a problem. Yes, it's meant for scripts.

#!/bin/tcsh -f

echo $?<

echo ok | ./script will return 3. My original idea is to return either 1 or 0. The way you put is fine, though.

The biggest problem is that the script will fail on systems that don't support FIONREAD. That's ugly, but, unfortunately, I don't know the best workaround for this.

zoulasc commented 3 months ago

Let's change the error message then. Can you also update the man page?

zoulasc commented 3 months ago

committed, thanks!

Krush206 commented 3 months ago

Do you think it would be any better to have a built-in command to list non-portable/unavailable features, @zoulasc? I was thinking on implementing something as such.

void dounfeats(Char **v, struct command *c)
{
    static char *unfeats[] = {
#ifndef FIONREAD
        "$?<",
#endif
        NULL
    };
    int i;

    for (i = 0; unfeats[i]; i++)
        xprintf("%s\n", unfeats[i]);
}

It could be issued prior to running the script. What do you think?

#!/bin/tcsh -f

foreach feat ( "`unfeats`" )
    if ( "$feat" == '$?<' ) then
        echo The script cannot be run. $feat is missing.
        exit -1
    endif
end

echo $?<
suominen commented 3 months ago

Compile time options that might affect the user are collected in the $version string. See tc.vers.c.

> echo $version:q
tcsh 6.24.12 (Astron) 2024-04-05 (x86_64-amd-NetBSD) options wide,nls,dl,al,kan,sm,rh,color,filec
Krush206 commented 3 months ago

Thanks. Shall I open a new PR, or will this be resolved later?

suominen commented 3 months ago

A new PR, please. :)